Reputation: 239
class adapter
{
private:
adapter& operator= (adapter& j)
{
cout<<"i m here"<<endl;
}
adapter(adapter&)
{}
public:
adapter()
{}
};
int main()
{
adapter* p = new adapter;
adapter* q = new adapter;
p = q;
return 0;
}
Here when q is assigned to p, it should throw compile time error because I have overloaded assignment operator in private section. But my compilation goes well. Anything I am missing here or doing wrong??
Upvotes: 0
Views: 166
Reputation: 24249
This is because you are not copying instances, but pointers. Infact, you are losing the pointer to one of your instances.
adapter* p = new adapter;
// translates to:
// void* ptr = alloc(sizeof(adapter));
// adapter* p = (adapter*)ptr;
// new (p) adapter(); // invoke the object's ctor.
adapter* q = new adapter;
// that allocated a new adapter on the heap and ctor'd it.
adapter x;
// this created an actual instance of adapter on the stack;
// when 'x' goes out of scope, because it's on the stack,
// it will be destroyed and it's destructor invoked.
adapter y;
// again, on the stack.
p = q;
// that copied the address of the second allocation into
// the first pointer, *losing* the first pointer. C++ does
// not have garbage collection, so this is called a leak.
x = y; // error: tried to use copy operator.
// this attempts to copy the instance "y" to the instance "x".
In addition to this, you also need to get the right fingerprint for the copy operator and ctor:
private:
adapter& operator=(const adapter&);
adapter(const adapter&);
class adapter
{
private:
adapter& operator= (const adapter& j);
adapter(const adapter&);
public:
adapter()
{}
};
int main()
{
adapter* p = new adapter;
adapter* q = new adapter;
*p = *q;
return 0;
}
If you want to prevent copying of pointers, you'll need to create a class to encapsulate them, or you'll want to look at std::unique_ptr.
Edit:
Prior to C++11 the normal pattern for "disabling" an operator is to leave it undefined:
private:
adapter& operator = (const adapter&); // name the parameter or not, it's optional.
If someone tries to use it from outside the class, you'll get a compile time privacy error. If something inside the class tries to use it, you'll get a linker error (which is fine when you're expecting it but a headache when you're in crunch trying to fix a release-postponing issue and it's complaining about an undefined function).
With C++11 you can mark it as deleted, which will result in more specific errors:
public:
adapter& operator = (const adapter&) = delete;
I've taken to making these public because some of the compiler versions I work with check the visibility first leading to old-style errors, whereas making it public allows them to reach the "hey, this is disabled" and give you the newer, more helpful errors they have when they encounter a delete'd function/operator.
Upvotes: 6
Reputation: 10345
p
and q
aren't adapter
s, but adapter*
, that is pointer to adapter
.
Worst of all, you're leaking memory:
int main()
{
adapter* p = new adapter; // first object of type adapter, p points to it
adapter* q = new adapter; // second object of type adapter, q points to it
p = q; // both p and q point to the second object now, first object lost
// no delete statement, so second object lost too.
return 0;
}
What you should do is either
int main()
{
adapter p;
adapter q;
p = q; // won't compile
}
or
int main()
{
std::unique_ptr<adapter> p = new adapter;
std::unique_ptr<adapter> q = new adapter;
p = q; // won't compile as unique_ptrs don't want you to let two variables point to the same thing
p = std::move(q); // will compile as you invoke the move-assignment operator.
}
I recommend using the first way.
Upvotes: 1
Reputation: 3281
You're not copying the adapter object, you're just copying the pointer. Try *p = *q.
Upvotes: 4