13 Replies - 737 Views - Last Post: 05 June 2012 - 11:01 AM Rate Topic: -----

#1 Crockeo  Icon User is offline

  • D.I.C Head

Reputation: 42
  • View blog
  • Posts: 247
  • Joined: 21-June 11

Classes vs. Class Pointers - When to use them, and why?

Posted 02 June 2012 - 10:01 PM

Hello C++ forum. It's been a while since I came here asking for help, but I was wondering something about how one is supposed to handle classes in C++. Namely, class pointers, or classes?


Before I start, by class pointers I mean something like this:
Class* class = new Class();



and by classes I mean
Class class;




Anyways, my question is in what situation should I use the class pointer and the class, respectively. Also, one problem I've been facing with just using the class, is calling a constructor. I'm not sure if it's possible in this manner, but I was wondering if it was.


Thank you for your help!
~Crockeo

P.S. -- Sorry for my C++-stupidity, when I used it a long time ago I didn't use it enough to get into classes and pointers.


EDIT: Also, forgive me for any grammar mistakes, 1 AM can do terrible things to one's brain.

This post has been edited by Crockeo: 02 June 2012 - 10:01 PM


Is This A Good Question/Topic? 1
  • +

Replies To: Classes vs. Class Pointers - When to use them, and why?

#2 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 1929
  • View blog
  • Posts: 5,741
  • Joined: 05-May 12

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 02 June 2012 - 10:05 PM

When you just declare a class within a scope, the class instance is created on the stack. When you leave the scope the instance is destroyed. When you create instance by calling new, a pointer to that instance in the heap is returned to you. That instance will stick around until you explicitly call delete. Both have their uses depending on your intended lifetimes for the instances.

This post has been edited by Skydiver: 02 June 2012 - 10:06 PM

Was This Post Helpful? 1
  • +
  • -

#3 jamesk479  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 30-May 12

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 02 June 2012 - 11:51 PM

View PostCrockeo, on 02 June 2012 - 10:01 PM, said:

Also, one problem I've been facing with just using the class, is calling a constructor. I'm not sure if it's possible in this manner, but I was wondering if it was.


Constructors can't be called. They execute automatically when a class enters scope.
Was This Post Helpful? 0
  • +
  • -

#4 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1394
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 03 June 2012 - 12:05 AM

> Constructors can't be called

Yes they can be. It's meaningful in the case of placement new.
Was This Post Helpful? 1
  • +
  • -

#5 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1690
  • View blog
  • Posts: 2,553
  • Joined: 21-June 11

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 03 June 2012 - 01:20 AM

View PostOler1s, on 03 June 2012 - 09:05 AM, said:

> Constructors can't be called

Yes they can be. It's meaningful in the case of placement new.


Constructors still get called automatically when using placement new (in fact the whole point of using placement new is to get the constructor to be called). You might be thinking about destructors, which do have to (and thus can) be called manually when using placement new.

Oh and to actually answer the OP's question (all pedantry aside): When using MyClass my_object;, the default constructor of MyClass will be called. To call a non-default constructor use:

MyClass my_object(my_constructor_arguments);

This post has been edited by sepp2k: 03 June 2012 - 01:30 AM

Was This Post Helpful? 1
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 4888
  • View blog
  • Posts: 11,284
  • Joined: 16-October 07

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 03 June 2012 - 12:34 PM

To answer the question, you use pointers in C++ when you must. A pointer introduces a clean up problem for the programmer; when to cleanup. If the class is declared concretely then cleanup taken care of for you when you leave scope.

The contructor is always called when the object, is, um, constructed.

This is really more fun with code.
#include <iostream>

using namespace std;

class Widget {
private:
	static int lastId;
	int id, value;
public:
	Widget() : id(++lastId), value(0) { print("constructor"); }
	Widget(int v) : id(++lastId), value(v) { print("constructor"); }
	~Widget() { print("destructor"); }
	int getId() const { return id; }
	int getValue() const { return value; }
	void print(const std::string &prefix) const { cout << prefix << ": "; print(); cout << endl; }
	void print() const { cout << "Widget(" << id << ")=" << value; }
};

int Widget::lastId = 0;


void test() {
	Widget w2(42), *w3, *w4;
	
	cout << "Haven't created instances for those pointers yet" << endl;
	w3 = new Widget(69);
	w4 = new Widget(144);
	
	cout << "clean up" << endl;
	delete w4;
	// oops, forgot w3, memory leak!!
	// note, w2 cleans itself up
}

int main() {
	Widget w1;
	
	test();
	cout << "back in main" << endl;
	return 0;
}



Results:
constructor: Widget(1)=0
constructor: Widget(2)=42
Haven't created instances for those pointers yet
constructor: Widget(3)=69
constructor: Widget(4)=144
clean up
destructor: Widget(4)=144
destructor: Widget(2)=42
back in main
destructor: Widget(1)=0



This is a pretty clean exit, actually. If you put output in destructors, you may not see an output depending on how things are running. Hopefully this illustrates the new and constructor questions.
Was This Post Helpful? 1
  • +
  • -

#7 Crockeo  Icon User is offline

  • D.I.C Head

Reputation: 42
  • View blog
  • Posts: 247
  • Joined: 21-June 11

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 06:47 AM

Thanks for the help everyone, this really cleared it up.

To summarize what I've been hearing is that using class pointers is more useful when you want to manually choose when that class will be destroyed, while using classes is preferred otherwise, correct?


Also, I noticed in your code that you initialized w2 when you declared it, but can you separate them?
Like:
Widget w2;
w2(42);


Was This Post Helpful? 0
  • +
  • -

#8 GWatt  Icon User is offline

  • member icon

Reputation: 257
  • View blog
  • Posts: 3,035
  • Joined: 01-December 05

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 06:58 AM

There's actually a trick you can do with pointers when you need them but don't want to handle the clean up.
#include <memory>

int main() {
    std::unique_ptr<Class> obj = new Class();
    return 0;
}


Since obj itself isn't a C style pointer, just a normal variable, it is deconstructed upon scope exit and the unique_ptr deconstructor handles all the heap management
Was This Post Helpful? 1
  • +
  • -

#9 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1690
  • View blog
  • Posts: 2,553
  • Joined: 21-June 11

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 07:00 AM

View PostCrockeo, on 05 June 2012 - 03:47 PM, said:

Also, I noticed in your code that you initialized w2 when you declared it, but can you separate them?
Like:
Widget w2;
w2(42);



No, that's not possible. The constructor is chosen when the variable is defined. You can not choose a different variable afterwards. If you need to pick the constructor after the variable has been defined, you need to make the variable a pointer and then pick the constructor when you call new.

Depending on the context you might also do this:

Widget w2;
w2 = Widget(42);



Note however that that's not the same as doing Widget w2(42);. The default constructor will still be called on line 1 (and if there's no default constructor, it won't compile) and then operator= will be called on line 2 with a temporary widget object as its argument.
Was This Post Helpful? 1
  • +
  • -

#10 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 4888
  • View blog
  • Posts: 11,284
  • Joined: 16-October 07

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 07:43 AM

It's generally consider preferable to declare and initialize in one step. So:
// ok
int i;
i = 42;

// better
int i = 42;

// or, for a C++y context
int i(42);



The reasoning is that there should never be an uninitialized variable floating around; it's asking for trouble. Also, you want a variable to only exist for as long as it need to, so declaring it only when you have a value for it fits this perspective.

If you have an object with values that change, that's fine. For Widget, you'd provide a setValue method in that case.
Was This Post Helpful? 1
  • +
  • -

#11 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 1929
  • View blog
  • Posts: 5,741
  • Joined: 05-May 12

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 09:13 AM

Another reason to choose to instantiate a class in the heap rather than the stack is if you need to conserve stack space.

Consider this:
// Some huge class
class Foo
{
     char fizz[4096];
     char bin[4096];
     char shralk[8192];
};

void Bar(int n)
{
     Foo foo;

     if(n > 0)
     {
          Bar(n - 1);
          // Do some work with foo
     }
}

int main()
{
     Bar(16);
     return 0;
}



You'll be eating a lot of stack space and eventually get a stack overflow. And then you'll be asking a question here or at stackoverflow.com asking "why am I getting a stack overflow in my recursive function even though I have a terminating condition and the recursion depth isn't that deep?"
Was This Post Helpful? 2
  • +
  • -

#12 GWatt  Icon User is offline

  • member icon

Reputation: 257
  • View blog
  • Posts: 3,035
  • Joined: 01-December 05

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 09:22 AM

In that case you should be allocating memory inside the class's member functions. If you set up your constructor/destructor properly then you don't have to worry about memory management for that class.
Was This Post Helpful? 1
  • +
  • -

#13 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 1929
  • View blog
  • Posts: 5,741
  • Joined: 05-May 12

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 10:40 AM

View PostGWatt, on 05 June 2012 - 09:22 AM, said:

In that case you should be allocating memory inside the class's member functions. If you set up your constructor/destructor properly then you don't have to worry about memory management for that class.


That is true if it's obvious like in the code above where the large chunks of memory are declared as class members. It becomes less obvious as class hierarchies start to form, and the when classes start using other classes as members. As you said, one approach is to always allocate those "chunky" bits on the heap instead of keeping them as class members, but you start paying the price of memory allocation overhead everytime in the constructor.

Here's a straw man:
enum Day : char {
    Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
}

class Week {
    Day days[7];    // Are you really going to allocate 7 days on the heap?
};

class Month {
    Week weeks[4];    // Are you really going to allocate 4 weeks on the heap?
};

class Year {
    Month months[12];    // Are you really going to allocate 12 months on the heap?
};
// I know: the year is going to be short 4 weeks.

int main()
{
   Year myYear;
}



336 bytes on the stack, no problem.

Later a program manager decides that the calendar should hold the name of the day so that you can have regular "Sunday" but also have "Mother's Day" or "Memorial Day Sunday". A new developer is tasked to make the change because it ought to be simple. Being mostly aware that of the hierarchy above, he knows that this is a bad idea:
class Day {
    char name[20];
};


because 336 * 20 == 6720 bytes on the stack for the Year would be bad.

Naively, thinking that it would be better to use std::string because it will dynamically allocate space as need. Additionally, he's always been taught in school that std::string is efficient, right? So he changes the code to:
class Day {
    std::string name;
};


because it seems awfully silly to write:
class Day {
    std::unique_ptr<std::string> name;

    Day() : name(new std::string) {
    }
}


if the std::string dynamically allocates inside anyway.

Alas, our hapless programmer just blew up the Year on the stack to 10752 bytes because he didn't know about the short string optimizations in the class. He should have gone with the std::unique_ptr<> to conserve the stack, or do a more extensive change and change all the others classes to use std::vector<> which will dynamically allocate instead of straight arrays.

The use of the std::<unique_ptr>() and std::vector<>() to dynamically allocate is exactly what GWatt advices, and seems to be a nice solution here.

In the end, it's a matter of knowing what your class does and what you expected usage pattern is.

And to get back on topic, if you know that Year is going to be large, use unique_ptr<Year> year(new Year); instead of Year year; :lol:

This post has been edited by Skydiver: 05 June 2012 - 04:06 PM

Was This Post Helpful? 1
  • +
  • -

#14 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 256
  • View blog
  • Posts: 1,669
  • Joined: 20-September 08

Re: Classes vs. Class Pointers - When to use them, and why?

Posted 05 June 2012 - 11:01 AM

View PostCrockeo, on 05 June 2012 - 09:47 AM, said:

Thanks for the help everyone, this really cleared it up.

To summarize what I've been hearing is that using class pointers is more useful when you want to manually choose when that class will be destroyed, while using classes is preferred otherwise, correct?


Also, I noticed in your code that you initialized w2 when you declared it, but can you separate them?
Like:
Widget w2;
w2(42);



Futher to the excellent comments above ... if you added a 'setter' to your class to set a private class value, then you could ...

class Widget
{
public:
   // ...
   void set_val( int n_val ) { val = n_val; }
   // ...
private:
   // ...
   int val;
} ;

// ...

Widget w2; // default ctor gets called ...
w2.set_val( 42 ); // call set_val member function (method) to set private data member val to be 42


Was This Post Helpful? 1
  • +
  • -

Page 1 of 1