How to Create Temporary Object in C++

How to create temporary object in C++

This is another instance of the "everything that can be a declaration is a declaration" rule. [stmt.ambig]/p1:

There is an ambiguity in the grammar involving expression-statements
and declarations: An expression-statement with a function-style
explicit type conversion (5.2.3) as its leftmost subexpression can be
indistinguishable from a declaration where the first declarator
starts with a (. In those cases the statement is a declaration.

The standard provides the following examples:

Assuming T is a simple-type-specifier,

T(a)->m = 7;       // expression-statement
T(a)++; // expression-statement
T(a,5)<<c; // expression-statement
T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; // declaration
T(*g)(double(3)); // declaration

In the last example above, g, which is a pointer to T, is initialized
to double(3). This is of course ill-formed for semantic reasons, but
that does not affect the syntactic analysis.

and also:

class T {
// ...
public:
T();
T(int);
T(int, int);
};

T(a); // declaration
T(*b)(); // declaration
T(c)=7; // declaration
T(d),e,f=3; // declaration
extern int h;
T(g)(h,2); // declaration

The simplest way to disambiguate is probably an extra set of parentheses. (A(a)); is unambiguously an expression-statement.

Temporary class object

Since c++11 you can use keyword auto if you don't want to specify type of variable explicitly, but don't confuse it with automatic variables, which means that they are deleted at the end of the block (you can read this: cppreference).

So at first line of function StrBlobPtr::end() constructor is called, object of type StrBlobPtr is created, after that copy constructor is called, another object is created but this object will exist until the end of block is reached (in this case end of function). First object is deleted after that, so you have only object created by the copy constructor. Please check this post:link.

Your second question is about returning object, if I am right. You must be careful when you do this in c++. Suppose you called StrBlobPtr::end() somewhere in your code:

StrBlobPtr obj; 
obj = StrBlobPtr::end();

So you created object in first line, after that you call function, object of the same type is returned but this object exists only in this line, after StrBlobPtr::operator=(StrBlobPtr x) is called object returned from function is deleted and it doesn't exists in memory, so you can't do:

StrBlobPtr* obj; 
obj = StrBlobPtr::end();

because after second line pointer obj have address of deleted object, and if you try to use it, you will get exception. So you must be careful if you want to return whole object from function, sometimes it is better to create object in dynamic memory with operator new and to return reference or pointer from function. It is important if you call this function often, every time you need to create object and to call copy constructor to return this object.

C++ create temporary object to call member function

"Most vexing parse": https://www.fluentcpp.com/2018/01/30/most-vexing-parse/

TestMe( a )() is being treated as a declaration of a function named a that takes no arguments and returns a TestMe object.

Change your program slightly so that the line in question doesn't conflict with the name a:

#include <iostream>

namespace
{
class TestMe
{
public:
TestMe() {}
TestMe( const std::string& me ) : me_( me ) {}

bool operator()() const
{
std::cout << "calling operator()" << std::endl;
return true;
}

private:
const std::string me_;
};
}

int main()
{
const std::string a("a");

//
// construct an instance of TestMe and call its operator()
//

TestMe()(); // OK
TestMe( "abc" )(); // OK
TestMe tm( a ); // OK
std::cout << "before most vexing parse\n";
TestMe( b )(); // compiles, but has no effect
std::cout << "after most vexing parse\n";
TestMe( { a } )(); // OK

return 0;
}

You will see that the line TestMe( b )(); produces no output because it's just a declaration:

calling operator()
calling operator()
before most vexing parse
after most vexing parse
calling operator()

Create temporary object as an argument on the stack

Why can't I just do something like:

DrawLine(Vector(0, 0), Vector(100, 100));

You're trying to pass temporary variables as argument. You can do it in 3 cases.

  1. If DrawLine takes parameters passed by const reference:

    void DrawLine(const Vector& v1, const Vector& v2);

  2. If Vector could be copied, and DrawLine takes parameters passed by value:

    void DrawLine(Vector v1, Vector v2);

  3. If Vector could be moved, and DrawLine takes parameters passed by rvalue reference:

    void DrawLine(Vector&& v1, Vector&& v2);

The only failing case is passing parameters by non-const reference, since temporary variable couldn't be bound to it.

void DrawLine(Vector& v1, Vector& v2);

Temporary object created in case of an object declared and then assigned

Is a temporary object created ?

Yes.

The expression Fixed( param ) will create a temporary object. This temporary object will then be passed to the assignment operator of the a object.

The statement

a = Fixed( param );

is somewhat equivalent to

{
Fixed temporary_object( param );
a.operator=( temporary_object );
}

Pointer to temporary object

Both codes have undefined behavior.

Here:

{
A a;
ptr = &a;
}

std::cout << ptr->value << endl; // "test"

ptr becomes invalid once a goes out of scope and gets destroyed.

Similar in the second example, you are also dereferencing an invalid pointer because the temporary string is gone after the call to the constructor.

C++ does not define what happes when you do things that are not defined (makes sense, no? ;). Instead it is rather explicit about saying that when you do certain wrong things then the behavior of the code is undefined. Dereferencing an invalid pointer is undefined. The output of the code could be anything. A compiler is not required to diagnose undefined behavior, though there are features and tools that can help. With gcc it is -fsanitize=address that detects the issue in both your codes: https://godbolt.org/z/osc9ah1jo and https://godbolt.org/z/334qaKzb9.



Related Topics



Leave a reply



Submit