• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 409
  • Last Modified:

C++ Programming Style - Using MyClass c = new MyClass(stuff) instead of MyClass c(stuff); Are Java style new MyClass() better than regular objects for C++ Dev?

Hi,

I've been recently creating a C++ based project of which I've been using Java style

//in class declaration
class Foo{
Foo();
MyClass * c;
MyBClass *b;
}


//in constructor
Foo::Foo(){
c = new MyClass();
b = new MyBClass();
}

style declarations. My question is, is this the regular way to create objects for class objects, or should I not use the "new" style (Java-like) method of instantiating classes within classes.

The biggest issue that comes up is that I want to be able to make *copies* of the values that these pointers point to, to be able to pass to other classes.

Lets say, I would do something like this:

Foo * myfoo = new Foo();

Foo * myfoo2 = myfoo; //which doesn't work, because I want to be able to modify myfoo2 without modifying myfoo :(.

Is this a pointer copy constructor issue? If so, how should I go about it? Is there some easy way to copy all values from within a class pointer into another class pointer?

Very much thanks in advance!

-Edward
0
edwardt
Asked:
edwardt
  • 9
  • 9
  • 4
  • +1
1 Solution
 
jkrCommented:
>> My question is, is this the regular way to create objects for class objects,
>>or should I not use the "new" style (Java-like) method of instantiating classes within classes

Both 'yes' and 'no'. You can of course use this technique, but have to make sure to 'delete' the pointers to the instances in your destructor. Depending on whether you *need* to use dynamic allocation, you alternatively could use

//in class declaration
class Foo{
Foo();
MyClass c;
MyBClass b;
}


//in constructor
Foo::Foo(){
}

>>The biggest issue that comes up is that I want to be able to make *copies* of the values
>>Lets say, I would do something like this:
>>Foo * myfoo = new Foo();
>>Foo * myfoo2 = myfoo; //which doesn't work, because I want to be able to modify myfoo2 without modifying
>>myfoo :(.
>>Is this a pointer copy constructor issue? If so, how should I go about it?

Again 'yes' and 'no'. If you want to make a copy of an object and do not want to touch the original, you could use


Foo * myfoo = new Foo();
Foo * myfoo2 = new Foo();

*myfoo2 = *myfoo; // assing the objects by value

which will work unless your classes become more complex. Thus, providing a copy constructor and an assignment operator before problems arise is good design, e.g.

//in class declaration
class Foo{
public:
Foo();
Foo(const Foo&r); // copy constructor
Foo& operator=(const Foo&r); // assgnment operator

protected:
MyClass  c;
MyBClass b;

 Foo& copy ( const Foo& r);
}

Foo::Foo(const Foo&r) // copy constructor
{
  copy ( r);
}
Foo& Foo::operator=(const Foo&r) // assgnment operator
{
   return copy ( r);
}
Foo& Foo::copy(const Foo&r)
{

    // assign each element to is corresponding value in our object

    a = r.a;
    b = r.b;

    return *this;
}

0
 
edwardtAuthor Commented:
Hi JKR,

For the most part, many of my items in my classes are pointers, like

class Foo{
Address *a;
AnotherClass b*;
RegularClass c;
char * d;
}

What additional benefit does making a copy constructor do beyond something like the  *myfoo2 = *myfoo; you have?

In light of

Foo& Foo::copy(const Foo&r)
{

    // assign each element to is corresponding value in our object

    a = r.a;
    b = r.b;

    return *this;
}

Do you mean I should put something like:

Foo& Foo::copy(const Foo&r)
{

    // assign each element to is corresponding value in our object

    a(r.a); //    a = r.a;
    b(r.b); //    b = r.b;
    c = r.c;
    d = r.d

    return *this;
}

And then make copy constructors for classes a and b as well?

Thank you again - this is a big help.

-Edward
0
 
jkrCommented:
>>What additional benefit does making a copy constructor dobeyond something
>> like the  *myfoo2 = *myfoo; you have?

*myfoo2 = *myfoo will invoke the copy constructor if one is present, making sure that each member will be copyied to the corresponding one in the target object.

>>Do you mean I should put something like:
>> [...]
>>And then make copy constructors for classes a and b as well?

Again, it is a good practise to provide copy constructors for non-trivial classes. It seems a little overhead at first, but the benefit is less error prone code...
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
AxterCommented:
>>My question is, is this the regular way to create objects for class objects, or should I not use the "new" style (Java-like)
>>method of instantiating classes within classes.

I recommend not using pointers if you don't need it.
If you're not getting any benifit in using the pointer, then you're better off using (static) non-pointers variables.

There's a greater risk for bugs when using pointers.
So your code is safer if you don't use them.
0
 
AxterCommented:
There are two main reasons for using pointers.
1.      Need to determine a virtual class descendant type at runtime
2.      Need to reference an object that does not have complete definition.

If neither applies to your object, then you shouldn’t use pointers.

There are other reasons like "circular reference", "class implementation hiding", etc....
However these other reasons fall in the above two categories.
0
 
edwardtAuthor Commented:
Ack! - Then that means I might need to go back to my (large) set of files and replace all class pointer members to regular members.

Then again, if I leave stuff as pointers, I would probably have to start adding a lot of stuff into the destructor functions :(.

I'm pretty sure there are areas where I *don't* want to have an addressed copy of a pointer. However, there are areas that I would want pointers... lemme see - (from http://www.harpercollege.edu/bus-ss/cis/166/mmckenzi/lect10/l10a.htm

Why use pointers?
Connect data structures in memory (lists, chains, queues, trees, graphs)
Allows a function to modify its arguments
Access dynamic memory (only way is via pointers)
Concise and efficient array access
Efficiently pass structure to a function

From these, I do need to pass these "classes" to functions regularly (very regularly!) and allow functions to modify their arguments.

So at the very least, I do need
1) To be able to make deep copies of classes pointers point to
2) to be able to modify arguments of classes I pass into functions.

Beyond that, I don't think there is much other requirements that I have to make me need to decide to use pointers instead of regular members. What do you think?

-Edward
0
 
edwardtAuthor Commented:
Ah - your second reason, Axter - 2.     Need to reference an object that does not have complete definition.

I think I need that because in some areas, I reference an object

BaseClass * b = somefunction->returnstuff();

where there are pure virtual functions of b, whose child classes implement the real function... If I did
BaseClass b = somefuction.... then it would give me an error, in that b hasn't implemented particular functions ;P (although I guess I could just implement those functions with a "blank" function in the .cpp file).

-Edward
0
 
edwardtAuthor Commented:
When I began thinking of these copy constructors, I realized that I also need to deal with the fact that my current class might have base class members that need to be copied. Is there a quick way to copy base class members too?

Also, I realized that sometimes I might need to figure out which child class I might need to deal with, like

MyBaseClass
MyClass
MyChildClass1
MyChildClass2

whereas, I might need to do a copy of

MyClass *c = getmyrealClass();//returns either a pointer to childclass1 or childclass2
MyClass *d = new MyClass(c); //whereas now, I have to

it could be something like
if(c is of childclass1){
d = new MyChildClass1(c);
} else {
d = new MyChildClass2(c);
}

right? :)

Thanks!


-Edward
0
 
AxterCommented:
>>Why use pointers?

I'm sorry, but that link is giving you some bad advise.
Those are not valid reason to use pointers, and certainly not valid reason to have a member variable as a pointer.

First point:
>>Connect data structures in memory (lists, chains, queues, trees, graphs)
Since you can use STL code for this, you don't need to use a member poitner.
Example
class foo
{
 public:
 std::vector<int> A_dynamic_array_of_int;
 std::list<int> A_list_of_int;

By using STL library, you can let it create the pointers, and it will also do the clean up automatically.

0
 
AxterCommented:
Second point:
>>Allows a function to modify its arguments

This is not a good reason at all.
Your variable does not need to be a pointer in order to have a function modify it.

Example:

void somefunction1(int &var)
{
 ++var;
}

void somefunction2(int *var)
{
 ++(*var);
}


int main()
{
  int MyVarThatIsNotAPointer = 0;
  somefunction1(MyVarThatIsNotAPointer ); //Pass via reference
  cout << MyVarThatIsNotAPointer << endl;
  somefunction2(&MyVarThatIsNotAPointer ); //Pass via pointer
  cout << MyVarThatIsNotAPointer << endl;

As you can see, MyVarThatIsNotAPointer is not a pointer, but it can be pass to a function that takes a reference, and it can be pass to a function that takes a pointer.
Both functions are able to modify the calling object's variable.
0
 
AxterCommented:
>>Access dynamic memory (only way is via pointers)

You can access and create dynamic memory via any of the STL containers.
std::vector
std::list
std::deque
std::map
etc...
All the above containers will create dynamic memory, and will handle the pointers for you, with regards to creating and deleting.
No need for you to have a pointer member variable for this reason.
0
 
AxterCommented:
>>Concise and efficient array access

The STL containers can give you concise and efficient access to an array.
This is another bad reason for having a pointer.
0
 
AxterCommented:
>>Efficiently pass structure to a function

More BS.
You variable does not need to be a poitner to pass a structure to a function.

Example:

void somefunction1(foofoo &var)
{
 //Do something to foofo
}

void somefunction2(foofoo *var)
{
 //Do something to foofo
}


int main()
{
  foofoo MyVarThatIsNotAPointer = 0;
  somefunction1(MyVarThatIsNotAPointer ); //Pass via reference
  somefunction2(&MyVarThatIsNotAPointer ); //Pass via pointer

As you can see, the above foofoo variable is not a pointer, yet you can pass it to a function that takes a pointer.
Moreover, you can efficiently, and more safely pass it to a function that takes a reference instead, in which case a pointer is not required at all.

References are just as efficient as poitners, and they're safer, easier to code, and easier to read.
0
 
AxterCommented:
edwardt,
If you look at the top of the link you posted, you would have notice the following:
Introduction to Programming in C

C has different rules then C++.
Moreover, there are some old C compilers in which SOME of those reasons would actually be valid.
For example, the Old Microsoft C compiler did not take reference arguments, you had to pass via pointers.
However, that still didn't mean you had to create the object using a pointer.
0
 
AxterCommented:
>>I think I need that because in some areas, I reference an object
>>BaseClass * b = somefunction->returnstuff();

Yes, that is a good reason for having a pointer.

>>When I began thinking of these copy constructors, I realized that I also need to deal with the fact that my current class might have base class members >>that need to be copied. Is there a quick way to copy base class members too?

You should create a copy constructor for the base class, so that it does the job of copying it's members.  This is not a job you want the decedant class to do.

Just remember, that when ever you use a pointer member variable, you add a lot more work for yourself.
For the class to be safe, you need to add a copy constructor, a assignment operator, and a destructor.
None of these are required if you use a non-pointer variable instead.
0
 
edwardtAuthor Commented:
In the case where I work with base classes

BClass *b1 = function->returnChildClass();
BClass *b2 = new BClass(b1);

lets assume that returnChildClass() returns some child class of BClass. ChildClass has its own members.

When I do b2 = new BClass(b1);, how do I make sure the member values of the child class (which is masqueraded as  BClass) make it into b2?

Thanks.

-Edward
0
 
edwardtAuthor Commented:
Another issue I come up with are that some members of my class have virtual functions, like

MyClass {

//members
AClass *a

BClass *b

}

where ACLass and BClass have virtual functions undefined... so when I do

MyClass & MyClass ::copy(const MyClass&r)
{
a = new AClass(*r.a)

return *this;
}

the compiler gives me errors, saying certain functions of AClass are virtual and not defined... the only way to fix this (it seems) is to go a level higher and instantiate the Child class, like
a = new ATheRightChildClass(*r.a);

But I'm not sure how to do that :P

-Edward
0
 
jkrCommented:
>>where ACLass and BClass have virtual functions undefined

You mean 'pure virtual' or just 'virtual'?
0
 
edwardtAuthor Commented:
Pure virtual... I guess I "could" make them virtual just to get past this issue... but then I still have the issue of copying members of child classes....

Thanks.

-Edward
0
 
jkrCommented:
>>Pure virtual

You cannot instantiate classes that have pure virtual members. You need to at least derive a class that implements these.
0
 
edwardtAuthor Commented:
Hi guys,

At the end I did end up making the copy constructors for a few classes, and it was very useful.

Thanks!

Axter - Another set of points for you to split. I'll create a question for that.

-Edward
0
 
stefan73Commented:
Hi Axter,
You forgot the good old NULL as a classic use for pointers :)

Cheers,
Stefan
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 9
  • 9
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now