问题
In short: is there some way I can modify a class definition such that it fails to compile at the point of use of a copy constructor no matter where it's used?
I have a very large project and was cleaning up some class definitions. There's a class that I explicitly don't want to use copy constructors on (let's ignore why that is for the sake of this discussion), and in the interest of safety, I figured I'd just define the copy constructor as private and not actually implement it... that way it would throw a compile error if I tried to use it anywhere. Lo and behold, it compiles fine, but I have a linker error... the copy constructor implementation is not found! Presumably that means it's in use somewhere, but I'm unable to find where it's being used. This is Visual Studio 2010 by the way. So my question is, is there some way I can modify the class definition such that it fails to compile at the point of use?
class Sample {
private:
// not implemented
Sample( const Sample& rhs );
Sample& operator=( const Sample& rhs );
public:
// implemented
Sample();
...
};
Sample *samp1 = new Sample;
Sample *samp2 = new Sample( *samp1 ); // <<-- inaccessible here! this works
Presumably since I'm not hitting a compile error, but am hitting the linker error, that it means the class itself (or a friend) is doing the copy-constructed create (since that's all that would have access to the private constructor), but I sure can't find it!
回答1:
in C++11 you can change the definition to
class Sample {
private:
// not implemented
Sample( const Sample& rhs ) = delete;
Sample& operator=( const Sample& rhs ) = delete;
public:
// implemented
Sample();
...
};
prior to C++11 this is usually done by inheritting from a class that declares a private copy constructor such as boost::NonCopyAble (you can simply copy this class, it's only a few lines). In this case your class (or any friends or children) also cannot access the copy constructor and it will generate a compile-time error.
回答2:
Inherit from a noncopyable class:
class noncopyable
{
private:
// not implemented
noncopyable( const noncopyable& rhs );
noncopyable& operator=( const noncopyable& rhs );
};
class Sample : private noncopyable {
private:
// not implemented
Sample( const Sample& rhs );
Sample& operator=( const Sample& rhs );
public:
// implemented
Sample();
// ...
};
Sample *samp1 = new Sample;
Sample *samp2 = new Sample( *samp1 ); // <<-- compile-time error
This works fine even if you don't have C++11 (where the delete
method mentioned elsewhere is probably preferable).
回答3:
What is error that linker generate? If it is LNK2019 it should be easy to track down function that uses copy constructor:
MSDN says that its format is:
unresolved external symbol 'symbol' referenced in function 'function'
If look this error message, you can find method that calls undefined copy constructor.
回答4:
Are you trying to get module+line number during compilation? Try making copy-constructor templated:
class A
{
public:
template< typename T >
A( A const & )
{
}
A()
{
}
};
int main( void )
{
A a;
A b( a ); // main.cpp(43) : error C2558: class 'A' : no copy constructor available or copy constructor is declared 'explicit'
return ( 0 );
}
回答5:
If the member is private then you should already get an error at the place of use if it doesn't have permission to access private members.
To get the same error in functions that do have private access you have to put the private copy-ctor declaration somewhere they don't have access to, like as a private member of a base class.
VS2010 doesn't support it yet, but declaring a function as deleted will also work.
回答6:
As I recall, if you declare it inline
, sometimes you'll get a compiler error that says it was declared inline but never defined. That was a while ago, and with gcc. YMMV.
[Shown not to work; leaving this for posterity.]
来源:https://stackoverflow.com/questions/9037330/how-can-i-find-where-a-c-copy-constructor-is-being-used-via-a-compile-error