Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent implementing a method that is intended to be non-implemented in C++? [duplicate]

Possible Duplicate:
What's the most reliable way to prohibit a copy constructor in C++?

Suppose I want to make a class non-copyable and want to prohibit copy constructor and assignment operator. I make them private and leave unimplemented:

class Class {
//useful stuff, then
private:
    Class( const Class& ); //not implemented anywhere
    void operator=( const Class& ); //not implemented anywhere
};

this way if any of them is accidentially called from within friends or the same class I get a link-time error.

Now what if a user implements them? I mean there's no implementation, so anyone can add his own:

Class::Class( const Class& )
{
    //whatever they want
}

Of course I could have created my own implementation and add an assertion there, but that would delay unintended calls detection until the program is run.

Is there a way to prevent implementing such method by a user and still have compile-time detection of unintended calls to them?

like image 987
sharptooth Avatar asked Apr 26 '11 06:04

sharptooth


People also ask

How do I make something non copyable?

Solution and Sample CodeEdit class NonCopyable { public: NonCopyable (const NonCopyable &) = delete; NonCopyable & operator = (const NonCopyable &) = delete; protected: NonCopyable () = default; ~NonCopyable () = default; /// Protected non-virtual destructor }; class CantCopy : private NonCopyable {};

What is boost NonCopyable?

Boost::noncopyable prevents the classes methods from accidentally using the private copy constructor.

What should be prohibited in C++?

Sometimes it's necessary to prohibit a copy constructor in a C++ class so that class becomes "non-copyable". Of course, operator= should be prohibited at the same time.

How to disable copy constructor C++?

A cleaner solution: create a class where the default copy constructor and/or default copy assignment operator are deleted. Derive all your classes or the base class of the class hierarchies from this special class. Copy construction and/or copy assignment will now be disabled for all these classes automatically.


4 Answers

In C++0x there is the new delete keyword, that does just this

What's the most reliable way to prohibit a copy constructor in C++?

like image 78
sehe Avatar answered Oct 02 '22 10:10

sehe


There is no problem here.

The client can provide implementations of those methods a much as they like, but the compiler will still complain because they're private.

Now, can you prevent someone hacking your header file, changing them to public and linking their own implementations?

Yes, provide your own implementations that throw exceptions, your hypothetical hacker will get a link error when they try to build.

In the normal course of events this doesn't slow anything down, as the compiler will never try to call those methods, and code that tries will be told

. . . cannot access private member declared in class . . .

In the case some "clever" gobshite tries, then yes the assertions will be delayed, but mate, that's not your problem, you can't protect every idiot in the world from shooting them selves in the foot.

+1 BTW, interesting question :)

. . . as pointed out by Xeo, the above only works for non templated classes

like image 38
Binary Worrier Avatar answered Oct 02 '22 10:10

Binary Worrier


Well the solution is like it is usually done in practice - use special non-copyable base class (e.g. boost::noncopyable or your own class). E.g.

class noncopyable
{
    // private
    noncopyable( const noncopyable& ); // not implemented
    noncopyable& operator=( const noncopyable& ); // not implemented

    // no friends, etc
};

Then somewhere

class A: noncopyable
{
// Anything ...
};

Obviously since there is no friends of noncopyable its copy constuctor and assignment operator is always private for everyone so it doesn't matter if it is implemented or not (compiler denies using them anyway).

like image 32
Serge Dundich Avatar answered Oct 02 '22 10:10

Serge Dundich


A bit of a non-answer to the question, but perhaps a different approach, depending a lot on what you're trying to achieve.

On the face of it, it sounds like you want compile time detection whilst you're developing the library in order to speed up detection and avoid relying on runtime testing identifying the issue.

If this is the case, can you not solve your problem by having two builds?

  • Build One (internal build): which builds the library and doesn't link in the copy constructor functions.

  • Build Two (client build): which links in the copy construction logic with asserts (from a different implementation file), so that there's runtime protection & the client can't provide their own implementation.

like image 36
forsvarir Avatar answered Oct 02 '22 10:10

forsvarir