Yes, it can - try the code if not believing... ;)Quote:
Originally posted by flysnow
So I don't think it can return a object by that way .
Mikey
Printable View
Yes, it can - try the code if not believing... ;)Quote:
Originally posted by flysnow
So I don't think it can return a object by that way .
Mikey
Mikey :
I think you are right .
"So I don't think it can return a object by that way . " I just say
Yes , it can return a object , but it doesn't use constructor directly to create temporary object .
now I belive it use constructor directly to create temporary object .
you are right . Thanks very much .
Mikey:
I found some evidences that your explanation had some problems.
Because if you return a object in a function , It use the copy constructor funciton to create this object instead of constructor function .
You can try the following code . so why we need a constructor function to create a temporary object is still a quetion .
Who can give me answer ?
#include "iostream"
using namespace std;
class T
{
public:
T() { cout<< " T constructed " <<endl ; }
~T(){ cout<< " T destructed " <<endl ; }
T( const T & )
{
cout <<" copy structor " <<endl;
}
T & operator = ( T & t ) { cout << " operator = " <<endl ; return *this; }
T GetSame() { return *this ; } //this function only call the copy constructor function instead of constructor to create a temporary object .
};
int main(int argc, char* argv[])
{
T t1;
T t2;
t2= t1.GetSame();
return 0 ;
}
I think there is some misunderstanding of the basic concepts...Quote:
Originally posted by flysnow
int main(int argc, char* argv[])
{
T t1;
T t2;
t2= t1.GetSame();
return 0 ;
}
Constructors are called when an instance of a class needs to be constructed without being assigned or returned or anything else...
In all the other cases the copy constructor or the assigment operator will be called...thus
The copy-constructor is called because both instances ('t1' and 't2') are already constructed. Therefore one instance just needs to be copied...Code:int main(int argc, char* argv[])
{
T t1; // Constructor
T t2; // Constructor
t2= t1.GetSame(); // Copy-constructor
return 0 ;
}
Quote:
Originally posted by Andreas Masur
I think there is some misunderstanding of the basic concepts...
Constructors are called when an instance of a class needs to be constructed without being assigned or returned or anything else...
The copy-constructor is called because both instances ('t1' and 't2') are already constructed. Therefore one instance just needs to be copied...
yes ,but I returned a object in a funciton , it should create a temporary object on stack. because return object is passed by value instead of by reference .
Does it make sence ?
Andreas :Quote:
Originally posted by Andreas Masur
The copy-constructor is called because both instances ('t1' and 't2') are already constructed. Therefore one instance just needs to be copied...Code:int main(int argc, char* argv[])
{
T t1; // Constructor
T t2; // Constructor
t2= t1.GetSame(); // Copy-constructor
return 0 ;
}
As per your explanation , It doesn't need to invoke the copy constructor , because it 's enough to invoke operator = .
t2= t1.GetSame();
but infact , this statement called the copy constructor first ,and then call = operator = funciton .
** galathaea's thoughts on reading :
This is getting a little scattered, so let's try to focus on the points being made and try to understand what confusion is happening here. It could be mine, but...
creates what is known as an anonymous instance of the class. This is a common idiom that does not need anymore expert advice than what has been given (Andreas and Mikey are two of the smartest posters here on CodeGuru in my opinion...). One common use is in a form of object factory (not common today, but at one point it was used rather widespread) where one creates symbol classes, ie. classes that have a name only (no members, basically a string precompiled into a more efficient form) as the overloaded parameter to decide which factory function to call.Code:ClassName();
Now a destructor gets called on every object created. So it depends on what objects are created. One can return a temporary object that then gets assigned into a given variable, something like
or copiedCode:MyObject = MyFunc(...);
but either way, the destructor is fired when the temp object finishes the sequence point it is attached to. So it is not only possible but quite easy for the temp object to last long enough for the copy or assignment, but no longer.Code:MyClassType MyObject(MyFunc(...));
or
MyClassType MyObject = MyFunc(...);
Any anonymous temporary object is not found in the same logical memory as the instantiated objects of the full code block (the c++ "stack", not necessarily related to a computers execution stack, though I know of no case where they are different). Instead, logically to the compiler, it exists only for the duration of the sequence points it encompasses. Everything else occurs through argument passing steps, which invoke copies or references. These argument passing steps may be of whatever function is called attached to the relevant sequence points, including operator=.
At least, this is how I understand things. If I err, there are plenty intelligent posters on these boards that will clean up my language...
In addition to what has been said:
There are obvious cases where a temporary created object could be eliminated by the compiler as an optimization. An example is:
The compiler had enough information to see that f() only calls g(), and that it does not need to create one copy of 't' to pass it to f() and another copy-of-the-copy to pass it to g(). This indeed was a legal optimization until the last amendment of the Standard. However, this is not a legal optimization for a compiler any more. The only situation where a compiler is allowed to bypass the creation of a temporary object is the optimization of the return statements.Code:void g(T t)
{
/*...*/
}
void f(T t){
g(t);
}
int main(){
T t;
f(t);
return 0;
}
In your example:
the compiler could otimize away the creation of the temp value -- but it is not oblidged to do so. If it doesn't, a temp variable is created with the copy-ctor and the operator = is invoked with the temp variable as rhs.Code:t2= t1.GetSame();
I didn't try to compile the code in release mode with full optimization -- but it would be interesting what the compiler makes out of it.
Note that against the naïve assumptions, following code:
calls the copy ctor when creating t2 -- and not the operator =, despite there being a "=" sign in that statement.Code:T t1;
T t2 = t1;
Yes , it will create anonymous instance .. but what we is discussing is why C++ need this feature ? when this feature can be use ?and why don't need scope like T::T() when you call the construtor ?Quote:
Originally posted by galathaea
creates what is known as an anonymous instance of the class. This is a common idiom that does not need anymore expert advice than what has been given (Andreas and Mikey are two of the smartest posters here on CodeGuru in my opinion...).
If a global funciton name is the same name with class T, Global function will be called instead of the class construtor function . This is a strange behavior .
I am not very clear about what you said . Can you explain it more detai? Thanks in advance .Quote:
One common use is in a form of object factory (not common today, but at one point it was used rather widespread) where one creates symbol classes, ie. classes that have a name only (no members, basically a string precompiled into a more efficient form) as the overloaded parameter to decide which factory function to call.
Here's an example from C++ for Real Programmers by Jeff Algers (proper props). This is to place the idiom in someone else's hands and defer questions of authority away from my timid self...
Its a really simple example in my opinion, and not necessarily the best option in most cases, but it generally shows one of the several reasons for a temporary object. Basically here you make a temporary VariationDad to give purely the type to distinguish which overloaded function to call. It was one of the first steps towards the major generic object factory idioms of today. Temporary object are also useful for many other cases of the general grammatical need: pass an argument to a function that generically determines the operation of the function, but this argument never needs to be referred to again outside the function block.Code:class VariationDad {};
class VariationAuntieEm {};
class Grandpa {
public:
static Grandpa* make(VariationDad);
static Grandpa* make(VariationAuntiEm);
};
// In your program
Grandpa* g = Grandpa::make(VariationDad());
Also, as mentioned before, this is a preferred meaning because design is worsened when one attempts to call one ctor from another (or anywhere else, for that matter). There should be a logical separation from construction-form dependent work and general object initialization, and it is best if this is represented in the class method structure. The question of why c++ implements the call to what would appear to be a ctor that way is thus: because it adds to the functionality of the language, whereas the naive ctor call would add nothing to the language that could not be accomplished by just adding an Initialize() method.
I disagree your opinion though you are an expert :)Quote:
Originally posted by Gabriel Fleseriu
In addition to what has been said:
There are obvious cases where a temporary created object could be eliminated by the compiler as an optimization. An example is:
The compiler had enough information to see that f() only calls g(), and that it does not need to create one copy of 't' to pass it to f() and another copy-of-the-copy to pass it to g(). This indeed was a legal optimization until the last amendment of the Standard. However, this is not a legal optimization for a compiler any more. The only situation where a compiler is allowed to bypass the creation of a temporary object is the optimization of the return statements.Code:void g(T t)
{
/*...*/
}
void f(T t){
g(t);
}
int main(){
T t;
f(t);
return 0;
}
The compiler can not optimize the code in this situation. because
the function g() may change the t ( parameter ) value . and because you pass the t by value ,so it can not impact on outside variable t .
so I think the compiler should create a copy -of the -copy to pass it to g(). otherwize you will change the value of outside variable t .
i
In this particular case, the compiler actually could optimize away one of the two copies. Think of it like this: f() does nothing with the copy it gets, except that it calls g(). So why create another copy just for g() to use?Quote:
Originally posted by flysnow
I disagree your opinion though you are an expert :)
The compiler can not optimize the code in this situation. because
the function g() may change the t ( parameter ) value . and because you pass the t by value ,so it can not impact on outside variable t .
so I think the compiler should create a copy -of the -copy to pass it to g(). otherwize you will change the value of outside variable t .
i
This reasoning doesn't hold on the general case because ctors can have side effects (like setting a lock or so) and the number of objects created must be predictable.
The issue is described in great detail in Herb Sutter's "Exceptional C++". Herb also touches the issue here
OK , I see .
Thank all of you for your zealous help :)
Believe it or not, you can actually call one constructor from within another constructor. Who would want that? I don't know. But you can do it if you really want to.
Constructors are just like other class member functions. It has a hiden "this" pointer. The problem that people don't usually explicitly call a constructor like a regular function call is, the object hasn't been constructed yet before the constructor, so you wouldn't have a object pointer to be used for the call to the constructor.
But in the case of one constructor call another constructor, we already have a this pointer. So the way to do it is like this:
Yes it works. You can even add some none-trivial class members like std::string and they will be constructed and then re-constructed, without being destroyed first before re-construction.Code:class T
{
public:
int m_i ;
T () { m_i = 1 ; }
T(int k ) { this->T::T(); }
};
To come back to a previous post, the reason why it calls the copy constructor first is because of the signature of the GetSame function:Quote:
Originally posted by flysnow
Andreas :
As per your explanation , It doesn't need to invoke the copy constructor , because it 's enough to invoke operator = .
t2= t1.GetSame();
but infact , this statement called the copy constructor first ,and then call = operator = funciton .
T GetSame(){return *this;}
This means that the function returns a temporary object. This temporary object is created here using the copy operator with *this as parameter.
Then it is copied to t2 (using the copy operator).
If you want to prevent this call to the copy constructor you should have:
const T& GetSame(){return *this;}