I have this code and I can understand what happening with the contractor of class Fat.
#include <iostream>
using namespace std;
class Block{
int data;
public:
Block(int i = 10) : data(i){
cout << "I just created a Block " << endl;
}
~Block() {
cout << "I will destroy a Block with " << data << endl;
}
void inc() {
data++;
}
};
class A{
Block& block1;
Block block2;
public:
A(Block& blk) : block1(blk), block2(blk) {
cout << "I just created an A " << endl;
}
A(const A& a): block1(a.block1), block2(a.block2) {
cout << "I just created an A by copying but I will also do bad things" << endl;
block1.inc(); block2.inc();
}
~A() {
cout << "I will destroy an A " << endl;
}
void inc() {
block1.inc(); block2.inc();
}
};
class Fat{
A a;
A& ra;
A* pa;
public:
Fat(A& da) : a(da),ra(da) {
pa = new A(da);
cout << "Fat just created !" << endl;
}
~Fat() {
delete pa;
cout << "Fat to be destroyed !" << endl;
}
void inc() {
a.inc();
ra.inc();
pa->inc();
}
};
int main(){
Block block;
A a(block);
Fat fat(a);
fat.inc();
return 0;
}
and the result of this :
I just created a Block
I just created an A
I just created an A by copying but I will also do bad things
I just created an A by copying but I will also do bad things
Fat just created !
I will destroy an A
I will destroy a Block with 12
Fat to be destroyed !
I will destroy an A
I will destroy a Block with 12
I will destroy an A
I will destroy a Block with 11
I will destroy a Block with 15
Why does the copy constructor run twice?
The first "I just created an A by copying but I will also do bad things"comes from this line:
Fat(A& da) : a(da), ra(da) {
a(da) this one calls A's copy constructor
the seconds one from the constructer of class fat:
Fat(A& da) : a(da), ra(da) {
pa = new A(da); //HERE!!
cout << "Fat just created !" << endl;
}
again, with pa = new A(da); you call A's copy constructor.
edit: thank you for formatting your code
The first copy is made to initialise the a member variable in Fat:
Fat(A& da) : a(da), ra(da) {
Then the line
pa = new A(da);
creates a new instance of A on the free store by copying da hence it calls the copy constructor. If instead you wanted to make a pointer to an existing instance of A you should write
pa = &da;
Related
I'm trying to learn a bit more about polymorphism and I tried to make it as simple as possible, so I got base class Figure and 2 derived classes Rectangle and Circle.
class Figure {
public:
Figure() { cout << "Creating Figure\n"; }
virtual ~Figure() { cout << "Destroying Figure\n"; }
virtual double calculateField() {
return 0;
}
};
class Rectangle : public Figure
{
public:
Rectangle(double m_a) : p_a(m_a) { cout << "Creating Rectangle\n"; }
~Rectangle() { cout << "Destroying Rectangle\n"; }
virtual double calculateField() {
return p_a*p_a;
}
private:
double p_a;
};
class Circle : public Figure
{
public:
Circle(double m_r) : p_r(m_r) { cout << "Creating Circle\n"; }
~Circle() { cout << "Destroying Circle\n"; }
virtual double calculateField() {
return p_r*3.14*3.14;
}
private:
double p_r;
};
In main function I create pointer to Figure class and 2 objects - rectangle and circle. Then I set Figure pointer on 1 of them and call calculateField() on this pointer. It works. But at the end I try to call delete on this pointer and it crashes my program.
int main(){
Figure *ptr = new Figure();
Rectangle rec(5);
Circle circ(5);
cout << "Figure field: " << ptr->calculateField() << endl;
ptr = &rec;
cout << "Rectangle field: " << ptr->calculateField() << endl;
ptr = ˆ
cout << "Circle field: " << ptr->calculateField() << endl;
delete ptr;
cin.get();
return 0;
}
Result of this looks like this:
Creating Figure Creating Figure Creating Rectangle
Creating Figure Creating Circle Figure field: 0 Rectangle
field: 25 Circle field: 49.298 Destroying Circle
Destroying Figure
But then I got Debug Assertion Failed
Expression: _BLOCK_TYPE_IS_VALID(pHead -> nBlockUse)
The program behaviour is undefined.
You can only call delete on the pointer you get back from new.
Currently you're trying to delete something that has automatic storage duration. That is never going to end well.
You actually create a simple Figure at Figure *ptr = new Figure();, but, you immediately leak it by re-using ptr in ptr = &rec;
And just before calling delete you once again re-used the pointer in ptr = ˆ, so in fact you are calling:
delete ˆ
which is obviously an error.
In fact, everything will be correct provided you never use ptr in new or delete but a different pointer:
Figure *ptr, *ptr2 = new Figure();
...
delete ptr2;
I have two classes, let's call them A and B
class A:
{
public:
//Some functions
A *getNewA() const;
private:
//some attributes
}
class B:
{
public:
//Some functions
private:
A &reftoA;
}
In the main code, I must generate a new A thanks to the A::getNewA() method. And this must go to B::reftoA, as written in class B.
Here is the A::getNewA() method :
A *A::getNewA()
{
A *newA = new A;
return newA;
}
OK. So now I call getNewA and want to store the results in reftoA, which is a reference to A. In a B function (which take a reference to A as parameter)
B::foo(A ¶mA)
{
reftoA = *(paramA.getNewA());
}
I thought this should have been working, but it won't.
Because when dereferencing, reftoA will always take the this object and not the new allocated object.
Let's be clearer and let's modify the functions to output the results
A * A::getNewA()
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return A;
}
void B::foo(A ¶mA)
{
reftoA = *(paramA.getNewA());
std::cout << "new generated pointer " << &reftoA << std::endl;
}
Here is one of the output :
New pointer : 004FFAEC
this pointer: 0069D888
New generated pointer : 0069D888 //Expected : 004FFAEC
I can't get this "new generated pointer" to be the same than the new pointer the A::getNewA() returns after having allocated the memory. Of course, I guess there is some point with dereferencing the pointer to store it in a reference.
I know reference are used with existing object. Maybe the new object A::getNewA() should allocate memory for won't work as I expected.
I could use pointer instead reference in B::foo(), I know, but I can't
I think I am misunderstanding something about refrence and pointer, but I don't know what.
Any help greatly appreciated
The problem is that you can not reassign a reference. You can change only the value of the referenced object.
So you have to initialize the reference in the initializer list of the constructor of the class B.
Take into account that there is a typo in your code snippet
A*A::getNewA()
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return A;
^^^^^^^^^
}
I think you mean
A*A::getNewA() const
^^^^^
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return newA;
^^^^^^^^^^^
}
Always try to provide a verifiable complete example.
Here is a demonstrative program
#include <iostream>
class A
{
public :
//Some functions
A* getNewA() const
{
A *newA = new A;
std::cout << "New pointer " << newA << std::endl;
std::cout << "this pointer" << this << std::endl;
return newA;
}
private :
//some attributes
};
class B
{
public :
B( const A& a ) : reftoA( *a.getNewA() )
{
std::cout << "&reftoA " << &reftoA << std::endl;
}
private :
A& reftoA;
};
int main()
{
A a;
B b( a );
return 0;
}
Its output is
New pointer 0x2b392afbec20
this pointer0x7ffd287ad0af
&reftoA 0x2b392afbec20
As you can see the values of the New pointer and &reftoA are equal each other.
To make it more clear consider a very simple example
#include <iostream>
int main()
{
int x = 10;
int y = 20;
int &r = x;
r = y;
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;
std::cout << "r = " << r << std::endl;
std::cout << std::endl;
std::cout << "&x = " << &x << std::endl;
std::cout << "&y = " << &y << std::endl;
std::cout << "&r = " << &r << std::endl;
return 0;
}
The program output is
x = 20
y = 20
r = 20
&x = 0x7ffd88ad47a8
&y = 0x7ffd88ad47ac
&r = 0x7ffd88ad47a8
This statement
r = y;
did not force the reference to refer the object y. It just reassigned the value of the referenced object x.
References have to be initialized when they are created.
Yes, you are misunderstanding something.
getNewA() is returning a pointer. it's not a smart pointer, you want to look into those and that's all I'll say on the matter.
on returning a pointer, you must keep a reference to this pointer else you will be unable to delete it and you'll get a memory leak. Thus you MUST have somewhere A* a = A::getNewA() and then later, when you no longer need it delete a;
Where you need to pass a reference to A, you can do foo(*a) which will dereference the pointer and pass a reference to the object it's pointing to.
But in summary, for all new code, smart pointers; there's no excuse to not use them.
Side note: Your code example had a few other issues; such as getNewA wasn't static; I'm going to take the code as a working example of your understanding, and not a working example.
Edit: On re-reading your example, the getNewA is intentionally non-static. I think this question is actually an XY problem (ie you're asking a question you've forced yourself into but isn't your actual problem); but I hope this addresses your misunderstanding of pointers and references.
You are not returning the pointer in the getNewA-Method
A* A::getNewA()
{
A *newA = new A;
return A; // you are returning A and not newA
}
And if you want to reassign the reference to a you can use a std::reference_wrapper
class B :
{
public :
void foo(A& paramA) {
reftoA = *(paramA.getNewA());
}
private :
std::reference_wrapper<A> reftoA;
}
Let us assume I have an Object MeasurementValues, which has n different pointers (this examples just show pointers to primitive types, but pointers to other complex objects mivght occur as well).
class MesaurementValues {
private:
int *measurement_1;
double *measurement_2;
long long *measurement_3;
//..
float *measurement_n;
int noPointer;
}
I know, this example might be a little bit contrived, anyway. I try to fullfill the Rule of Five in my code.
Do I have to
this.measurement_x = old.measurement_x ;// for all x = {1,..,n} ?
First off just be aware that move-semantics give no advantage over copy-semantics for plain-old-data type (POD) members, but it sure does when your class contains other class objects and/or arrays. When you implement move-semantics, it means you have a "move constructor" and/or a "move assignment operator" which would look like this in your class:
class MesaurementValues { private:
int *measurement_1;
double *measurement_2;
long long *measurement_3;
//..
float *measurement_n;
int noPointer;
//a couple different objects
someObject* pObj1;
differentObject* pObj2;
public:
MeasurementValues( MeasurementValues&& move ); //move-constructor
MeasurementValues& operator= (MeasurementValues&& move); //move-assignment
}
-Assuming your class has POD data and class objects, and
-assuming there are alot of variables to move over:
MeasurementValues::MeasurementValues( MeasurementValues&& old) {
//copy plain-old-data over
measurement_1 = old.measurement_1;
measurement_2 = old.measurement_2;
//copy over values of the pointers
pObj1 = old.pObj1;
pObj2 = old.pObj2;
}
Keep in mind that move-semantics, as other posters have said, only have an advantage if your data members are other moveable objects, or dynamically-allocated memory.
EDIT:
pointers in must become "invalid", as they've been moved. Therefore I would set them to null to prevent unexpected behavior:
MeasurementValues::MeasurementValues( MeasurementValues&& old)
: measurement_1() //null...
//,...
{
//Swapping null into old...
std::swap(measurement_1, old.measurement_1);
//...
}
Do I have to
this.measurement_x = old.measurement_x ;// for all x = {1,..,n} ?
I would rely on the pimpl idiom for this, and use something like a unique pointer. Below is a detailed example. Note you only have to work with Impl, and rely on its defaults (as it contains no pointers).
#include <iostream>
#include <memory>
struct Moveable
{
public:
Moveable();
~Moveable();
Moveable(const Moveable& m);
Moveable& operator=(const Moveable& m);
Moveable(Moveable&& m);
Moveable& operator=(Moveable&& m);
int foo() const;
private:
struct Impl;
std::unique_ptr<Impl> pimpl_;
};
//Moveable.cpp
struct Moveable::Impl
{
Impl(): a(1), b(2), c(3), buffer(){}
int a, b, c;
char buffer[10000]; //Make it worth our while...
};
int Moveable::foo() const{ return pimpl_->a+pimpl_->b+pimpl_->c;}
Moveable::Moveable()
: pimpl_(new Impl)
{
std::cout << "Default " << (void*)this << std::endl;
}
Moveable::~Moveable()
{
std::cout << "Destruct " << (void*)this << std::endl;
//automagically...
}
Moveable::Moveable(const Moveable&m)
: pimpl_(new Impl(*m.pimpl_))
{
std::cout << "Copying " << &m << " to " << (void*)this << std::endl;
}
Moveable& Moveable::operator=(const Moveable& m)
{
std::cout << "Copy assign " << (void*)&m << " to " << (void*)this << std::endl;
*pimpl_ = *m.pimpl_; //Relying on their defaults...
}
Moveable::Moveable(Moveable&& m)
: pimpl_(move(m.pimpl_))
{
std::cout << "Moving " << (void*)&m << " to " << (void*)this << std::endl;
}
Moveable& Moveable::operator=(Moveable&& m)
{
pimpl_ = move(m.pimpl_);
std::cout << "Move assigning " << &m << " to " << (void*)this << std::endl;
}
int main()
{
Moveable x;
Moveable y(x); //Copying...
y = x; //Copying assign
y = Moveable(); //Default construct, then move assignment, destruct temp
Moveable z(std::move(y));
std::cout << "Calling foo " << z.foo() << std::endl;
return 0;
}
I have a question regarding the following code, which crashes. I am creating a local variable in testfunction() and then pushing it (variable "y") into a list. This variable has a member pointer "b" of object type Ball. As I understand, this local variable "y" is on the stack, so its' destructor will be called after testfunction() is completed. Also, as I understand, a vector "copies" an object into its' list. From what I've learned, it is best practice to delete a pointer in the destructor if one exists in its' class. So, there is "delete b" in the destructor of Example.
The issue that I am having is that the object y.b is being destroyed at the completion of testfunction(). In main(), I am able to see the value of "name" and the address of "b", but the object "b" has already been deleted. I would like to avoid this.
I think there is an issue with the design of the code/use of pointers vs references, etc. Please guide me in the right direction, I am an idiot!
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Ball
{
public:
int a;
Ball()
{
a = 0;
}
~Ball()
{
cout << "destroyed Ball()" << endl;
}
};
class Example
{
public:
string name;
Ball* b;
Example()
{
name = "";
b = NULL;
}
~Example()
{
cout << "destroying Example()" << endl;
delete b;
}
};
void testfunction(vector<Example>& list)
{
cout << "entered testfunction1()" << endl;
Example y;
y.name = "myName";
y.b = new Ball();
y.b->a = 5;
cout << "y.b->a = " << y.b->a << endl;
list.push_back(y);
cout << "exit testfunction1()" << endl;
}
void testfunction2()
{
cout << "entered testfunction2()" << endl;
Example* y = new Example();
cout << "exit testfunction2()" << endl;
}
int main() {
vector<Example> list;
testfunction(list);
//testfunction2();
if(list[0].b == NULL)
cout << "b is null" << endl;
else
cout << "b is not null" << endl;
cout << list[0].name << endl;
cout << list[0].b << endl;
cout << "list[0].b->a = " << list[0].b->a << endl;
return 0;
}
Since class Example has a pointer member and it tries to own a dynamically allocated resource, it needs non-default copy operations, in other words, it needs user-defined copy constructor and assignment operator.
Inside testfunction, when you copy y into vector, both local y and y copied to the vector point to very same Ball object. The local y is destroyed at the end of the function and Ball is deleted. However, that deleted Ball still pointed by the y in vector
void testfunction(vector<Example>& list)
{
// ...
Example y;
y.name = "myName";
y.b = new Ball();
y.b->a = 5;
list.push_back(y);
// ...
} // <-- destructor for Example y is called and y.b is deleted
Define a copy constructor and an assignement operator for your class Example.
These shall copy properly your object (creating a duplicated Ball object) when pushed back on the vector.
Example(const Example& a)
{
name = a.name; // attention no dynamic allocation
cout << "copy" <<endl;
if (a.b) {
b = new Ball(*a.b); // create a new duplicated Ball
}
else b = NULL;
}
The problem in your example is that the default copy constructor is called when you pushback the object. It copies memberwise and so the pointer to Ball is copied, not the object pointed to.
Yet another alternative could be to replace your Ball* with shared_ptr<Ball> (and accordingly, new Ball with make_shared<Ball>() and the delete b of the object with a b.reset()). The principle is that this smart pointer keeps track of the number of time the object pointed to is used, so that it will not delete it twice, but only when its no longer used anywhere.
I have a doubt about the scope and the memory management in c++. Here is the case I'm having troubles:
Abc function f()
{
Abc c;
return c;
}
Abc d = f();
if(d) cout << "hi";
Would it say the "hi"? I mean... the Abc created in f() is not dynamic (we didn't write a new)... but we are returning the value, so we mantain a reference to the object. Would it has value, or as soon as it gets out of its scope it dies?
Thanks!
#include <iostream>
using std::cout;
using std::endl;
class Abc
{
int m_value = 0;
public:
Abc()
{
cout << "Default Constructor" << std::endl;
}
Abc(const Abc& _source)
{
cout << "Copy Constructor" << std::endl;
//copy stuff
}
Abc& operator=(const Abc& _source)
{
cout << "assignment operator" << std::endl;
if (this == &_source)
return *this;
//copy stuff
return *this;
}
Abc(const Abc&& _source)
{
cout << "Move Constructor" << std::endl;
//move stuff
}
Abc& operator=(const Abc&& _source)
{
cout << "move assignment operator" << std::endl;
//move stuff
return *this;
}
~Abc()
{
cout << "Destructor"<< std::endl;
}
void setValue(int _value)
{
m_value = _value;
}
int getValue()
{
return m_value;
}
};
Abc f()
{
Abc c;
c.setValue(100);
cout << "c value: " << c.getValue() << endl;
return c;
}
int main()
{
Abc d = f();
cout << "d value: " << d.getValue() << endl;
d.setValue(200);
cout << "d value: " << d.getValue() << endl;
}
Here is the output:
Default Constructor
c value: 100
d value: 100
d value: 200
Destructor
From here you can see that the compiler is smart enough to reuse allocated object without making any dumb copies(C++98/03, C++11 same output).
Compiled with MinGW(GCC 4.7.1).
In your case it is impossible to make an exact statement, in the second case below:
Abc* function f()
{
Abc *c = new Abc();;
return c;
}
Abc* d = f();
if(d) cout << "hi";
And yes, it would say "hi", the difference is that in the first case, c is kept in Stack while in the second case it is kept in Heap. In your case, typing if(d) is not a good method for checking whether object is alive because it is defined on the Stack.
In order to check your case you can add a log to the destructor of Abc and see whether it will be hit or not. You will observe that the destructor of Abc is called when you return the object with f(). But this does not mean that the object is dead. Only its destructor is called. But in this case you can not use destructors properly. This is one of the reasons why pointers to objects are chosen instead of defining them directly.
Abc f()
{
Abc c;
return c;
}
create c of type Abc, copy it and return from function (with NRVO copy may be elided).
Abc d = f();
if(d) cout << "hi";
create d and copy-initialize it with returned value of function f. What is Abc type? If it has operator bool (or operator T() where T is implicitly convertible to bool) - may be it will print "hi".