C code
#include <stdio.h>
typedef struct
{
int a;
}A;
int main()
{
A(); // this line gives error
return 0;
}
Output
Error: Expected identifier or '('
C++ code
#include <iostream>
struct A
{
int a;
A()
{
std::cout<<"Ctor-A\n";
}
~A()
{
std::cout<<"Dctor-A\n";
}
};
int main()
{
A(); // creates temporary object and destroyed it
return 0;
}
Output
Ctor-A
Dctor-A
I know about the "Rule of three", but code becomes complicated and most compilers don't give errors if we don't follow the rule. So I avoided creation of a copy constructor and an overloaded assignment operator.
Why does A()/A{} create a temporary object in C++, but not in C? What's another way to create a temporary object in C?
In C (C99 and later) you can create a structure with automatic lifetime using a Compound Literal.
The syntax is (A){ initializers, for, struct, members }.
The lifetime is automatic, not temporary, so the structure created in this way does not vanish at the end of the full-expression, but at the end of the enclosing scope.
This expression
A()
is considered by C compilers as a function call. In C++ such an expression means a call of a constructor provided that A is a class type.
To create a temporary object in C you could declare a function like for example
struct A { int a; } A( int x )
{
struct A a = { .a = x };
return a;
}
and then you can call the function creating a temporary object of the type struct A like
A( 10 );
Here is a demonstrative program.
#include <stdio.h>
struct A { int a; } A( int x )
{
struct A a = { .a = x };
return a;
}
int main(void)
{
struct A a = A( 10 );
printf( "a.a = %d\n", a.a );
return 0;
}
The program output is
a.a = 10
A() calls the constructor for the struct A in the C++ code. However, C doesn't support constructors / destructors, or even objects (in the sense of OOP) in fact. The only way to create a temporary object as you describe in C would be to declare a variable of type A and wait for it to go out of scope, where the memory allocated for it will be popped from the stack, or to allocate a variable on the heap and free it in the next line.
Related
Per my understanding, I know that when an object is instantiated, a constructor is called once. But I can't understand why both constructors are called and only one object is instantiated
#include <iostream>
using namespace std;
#define print(me) cout << me << endl;
class A
{
public:
A() { print("default called"); }
A(int x) { print("paramterized called"); }
};
int main()
{
A a;
a = A(10);
return 0;
}
I got output:
default called
parameterized called
In these lines
A a;
a = A(10);
there are created two objects of the type A. The first one is created in the declaration using the default constructor
A a;
And the second one is a temporary object created in the expression A( 10 )
a = A(10);
that then is assigned using the copy assignment operator to the already existent object a.
Due to the copy elision you could avoid the use of the default constructor by writing initially
A a = A( 10 );
In fact due to the copy elision it is equivalent to
A a( 10 );
provided that the copy constructor is not declared as explicit.
You are also calling function while creating it with A a;
You can solve it by initializing value while creating it like this:
int main()
{
A a = A(10);
}
Or as a Fareanor said :
int main()
{
A a(10);
}
[at line 14th where f().i = 10,the Xcode said Expression is not assignable,why?Is it illegal?]
class A{
public:
int i;
A():i(0){}
};
A f()
{
A a;
return a;
}
int main() {
f().i = 10;
return 0;
}
f() produces a temporary. C++ doesn't allow assigning to a member of a temporary. Formally, f().i is an xvalue, while assignment requires an lvalue.
Such an assignment would be rather pointless anyway, as the temporary would get destroyed very soon afterwards.
I have been thinking and searching this but I can't solve this question.
I would like an object that when copied into another object, both objects share certain member variable. So, when I change the value of the member variable of object1, it's also changes the variable in object2. Example:
class ABC {
public:
int a = 5;
//...
}
int main() {
ABC object1;
ABC object2 = object1;
object2.a = 7; // now, object1.a is equal to 7
object1.a = 10; // now, object2.a is equal to 10
}
I know about copy constructors, but I am not sure if it applies here or there is
a better method. I have been thinking about using pointers or references, but can't make the trick.
Note that I don't want all the objects to share the same variable.
What you need is a pointer. The pointer points to the object and then all objects that copy the first one just copy the pointer so that they all point to the same thing. To make life easy we can use a std::shared_ptr to manage the allocation and deallocation for us. Something like:
#include <memory>
class Foo
{
private:
std::shared_ptr<int> bar;
public:
Foo() : bar(std::make_shared<int>()) {}
int& getBar() { return *bar; }
};
int main()
{
Foo a;
a.getBar() = 7;
Foo b = a;
b.getBar() = 10;
// now getBar returns 10 for both a and b
Foo c;
// a and b are both 10 and c is 0 since it wasn't a copy and is it's own instance
b = c;
// now b and c are both 0 and a is still 10
}
I want to know is it okay if i will use following method? There is no syntax errors and any warnings but i want to know is there any memory problems?
#include <iostream>
using namespace std;
class test {
int* x;
public:
test(int *n) { this->x = new int(*n); }
inline int get() { return *x; }
~test() { delete x; }
};
int main(void) {
while(1){
test a(new int(3));
cout << a.get() << endl;
}
return 0;
}
You have 2 issues in your code:
your class violates rule of three/five/zero
you are leaking memory when create a
In this code:
test a(new int(3));
you dynamically allocate int with value 3 and pass to a ctor which uses value and creates it's own dynamically allocated int. After that this memory is leaked. If you want to pass dynamically allocated data to a class use a smart pointer:
class test {
std::unique_ptr<int> x;
public:
test(std::unique_ptr<int> n) : x( std::move( n ) ) { }
int get() const { return *x; }
};
int main()
{
x a( std::make_unique<int>( 3 ) ); // since c++14
x a( std::unique_ptr<int>( new int(3) ) ); // before c++14
...
}
and you do not need to implement dtor explicitly, you do not violate the rule and it is safe to pass dynamically allocated data to ctor.
Note: I assumed you used int as example and you would understand that dynamically allocate one int is useless, you should just store it by value.
You are violating the rule of 3 (5 since c++11). It means that since you defined the destructor you should define the copy/move constructor/operation.
With your implementation, the copy/move constructor/operation are wrong. When you copy your object, it will do a shallow copy of your pointer and will delete it therefore you will have a double delete. When you move it, you will delete a pointer you didn't allocated.
Bonus point: your inline is useless
I was playing with an idea where i can have variables in global scope but not construct them. Note that there IS a placement new being ran. However i'd like to know what is undefined or incorrect about this code
#include <new>
#include <cstdio>
#include <typeinfo>
//#define AlignAs alignas(T)
#define AlignAs
template<class T>struct BlockOf {
AlignAs char t[sizeof(T)];
operator T&() { return reinterpret_cast<T&>(*this); }
~BlockOf(){((T*)&t)->~T(); }
};
struct B{
virtual void v(){}
~B() { printf("B\n"); }
};
struct A: B{
A(){printf("a\n");}
int regularDots;
void v() { printf("A virtual\n"); }
};
BlockOf<A> _a;
A&a=_a;
void init(){
new(&a) A;
}
int main() {
init();
A aa;
a.regularDots=9;
printf("%s %s %d %d\n",
typeid(a).name(),
typeid(aa).name(),
typeid(a).hash_code()==typeid(aa).hash_code(),
sizeof(a) == sizeof(aa)
);
B *b = &a;
b->v();
}
This isn't clear
operator T&() { return *reinterpret_cast<T*>(this); }
Instead use
operator T&() { return reinterpret_cast<T&>(t[0]); }
I think that this is required to point at the first member, but using the array explicitly seems safer to me.
To answer your main question, 3.8p8 contains the restrictions on reusing memory belonging to a variable with static storage duration, and since the original type has a trivial destructor, you should be ok.
If a program ends the lifetime of an object of type T with static (3.7.1), thread (3.7.2), or automatic (3.7.3) storage duration and if T has a non-trivial destructor,
the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined.