Click here to Skip to main content
15,114,127 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hello people.
Who can explain, why when we need to set some data members in some class, sometimes we use:

1) accesors like
void setSomeData(int mydata){itsdata = mydata}; // if we use default constructor??? 

2) sometimes we use constructors like
myConstructor(int mydata){itsdata = mydata} // to set some data members;

3) if we use inheritance some times we use for example
Mammal():itsAge(2), itsWeight(5){} // why whis?
I don't understand the third, why we can't set like
Mammal(int age, int weight) { itsAge = age; itsWeight = weight }
???
Whitch type is better to use and when?
=======================================
And who can tell me how to set some data memebers with constructor by referece and also by pointer?

for example if i have:

class myClass
{
   private:
           itsAge;
   public:
          myClass(int age) { itsAge = age }; 
// what happens if (int &age) ???
          ~myClass();
};

....
....
myClass cow(3);
&newCow = cow; // does it refer my data to myclass data member by reference?


I'm confused with this so asking for your help. I also read tutorials, but can't understand fully.
Posted

There is no "better" way to do it. Here are my personal rules

0) If you are bound by coding guidelines relating to constructors, follow them. Period.

Otherwise...

1) If you are editing an existing file, follow the coding style used in the file

2) If you are creating a new file, do it however makes sense to you.
   
Comments
MNMR 7-Apr-11 14:36pm
   
Yep John. I'll do it anyway.
   
Make sense (my 5). However, I see some rationale behind using the form (3). I think its preference is quite explainable. Please see my Answer.
--SA
walterhevedeich 7-Apr-11 21:34pm
   
Voted 5.
1) This is can be used as an accessor; you are right. If you need to modify the field of the already constructed class instance, what else can we do? We can use this accessor or side effect from some (non-const) instance (non-static) function called on this instance.

2) This form of writing constructor is not preferred, preferred on is (3)

3) This is the preferred form of field initialization in the constructor. It has nothing to do with inheritance at all as it can be used on the type completely isolated from any inheritance. However, you can use it with inheritance. Remember two things: automatic call of the base class constructor and one important warning: you should not call virtual functions from a constructor. The explanation of this is pretty complex; if I find the article on this topic, I'll add the reference for you.

I guess, you confusion is all about why (3) is needed; and now you may want to know why I call (3) a preferred way? The short answer is: this is due to the C++ ideology. More exactly, this is based on the fundamental difference between initialization of the object and assignment operation. Is assignment is not possible, the initialization always takes place. I think this special syntax for initialization by constructor is used to strictly isolate "just initialization" from any other code which can cause side effects. The form (3) can only be used for initialization, which reduces the risk of some bugs based on the difference between initialization and assignment.

[EDIT]
The form (3) is basically preferred, but not in all cases.
AspDotNetDev recently offered me a very simple example where the form (2) is much better, please see http://www.codeproject.com/Messages/3849028/Code-Sharing-Cplusplus-Intitialization-List-Expens.aspx[^].
[END EDIT]

There is no essential difference between setting up of the class instance fields by value, by reference or "by pointer". You rather need to read about different ways of passing parameters. Additionally, pay attention on how the const modifier is used and treated. By the way, "by pointer" in not a separate mechanism of passing parameters. It is actually passing some parameter by value, but the parameter itself can be of pointer type or not. However, these two cases create identical binary code: a) you pass a variable of the type T by reference, b) you pass a variable of the type *T by value. Despite identical binary semantics, the syntax is different for both the caller and the function implementation. I would say passing *T is more the legacy of C style; passing by reference (&T) is often preferable (but not always possible).

Here is one example when one may prefer by reference: with pointer-by-value approach one can pass null pointer. It can be prevented using the by-reference.

You also need to read about C++ references per se. And l-value. Don't mix reference type notation with "address" operator "&".

Sorry, I can't see any sense in you last question related to two last line of your code about caw and newCaw. As you did not declare newCaw, its even harder to guess what did you mean to achieve or understand. I guess you can understand it if you read about C++ references.

—SA
   
v4
Comments
Nish Nishant 7-Apr-11 20:15pm
   
Good points, SA. Voted 5!
   
Thank you, Nishant.
I just added a note offered by AspDotNetDev and his reference to the example where the form (2) is much better.
--SA
walterhevedeich 7-Apr-11 21:33pm
   
Good point. High 5. :)
   
Thank you.
--SA
LaxmikantYadav 8-Apr-11 7:57am
   
My 5 - Nice explaination
   
Thank you, Laxmikant.
--SA
There are many different uses for the constructs you've described, and it would be much easier to choose between them given a usage scenario. However, one thing I will note is that your third item is making use of an initialization list.

Initialization lists can be used to pick which parent constructor will be called and to initialize variables. They are required when the parent class does not have a default constructor, when initializing reference fields, and when initializing const fields.

You can read more about initialization lists here: http://www.cprogramming.com/tutorial/initialization-lists-c++.html
   
v3
Comments
   
Thank you for giving one of the required references -- I never know what to suggest to read on C++. My 5.
As to the preference of the form of the constructor, I think I explained rationally why (3) should be preferred, please see my Answer.
--SA
AspDotNetDev 7-Apr-11 15:12pm
   
Yeah, it makes good sense to prefer (3) in most scenarios. Though I can imagine scenarios where (2) would be the ideal choice. For example, if you use one parameter to calculate a value that is then modified and assigned to two of the fields. If the first calculation is expensive or speed is critical, avoiding an initializer list in favor or reusing a local variable multiple times may be the better approach.
   
[I did not understand the idea, text removed]
--SA
AspDotNetDev 7-Apr-11 16:37pm
   
I don't really follow you, but I made a code snippet so you can see exactly what I'm talking about: http://www.codeproject.com/Messages/3849028/Code-Sharing-Cplusplus-Intitialization-List-Expens.aspx
   
Thank you.
Oh, I certainly did not understand you, because your code in this sample still shows the use of (3). I though you wanted to illustrate something where (2) is preferred... so now I don't understand your case where the form (2) is preferable...

By the way, this samples shows a good point. Oh no, now I understand it completely. You just show both options... Well, I agree! This is a clear point where form (2) should be used. Great point! Thank you.
--SA
AspDotNetDev 7-Apr-11 17:13pm
   
Glad I could help. Sorry to confuse you. I should have posted two different code snippets, but I'm lazy :-)
   
"Laziness is a driving force of progress"... :-)
Thank you.
--SA
   
So, thanks to this example, I fixed my Answer and added a reference to you code showing this case.
Thank you!
--SA
walterhevedeich 7-Apr-11 21:33pm
   
Good point. High 5. :)
It is now much clearer. Especially grateful SAKryukov, which is not lazy to explain. Your help is very valuable, thanks man. :)
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900