Which is the difference between declaring a constr

2019-02-12 01:12发布

For example, I want to declare a class but I want the client to not be able to use the copy constructor (or copy assignment operator)

Both of the following two does not allow the use of the copy constructor:

1.

class Track
{
public:
  Track(){};
  ~Track(){};
private:
  Track(const Track&){};
};

2.

class Track
{
public:
  Track(){};
  ~Track(){};
  Track(const Track&)=delete;
};

Is one of these ways "more correct" than the other or are equal? Is there any side-effect?

//Does not compile with both the above ways
int main()
{
  Track l;
  Track p(l);
}

7条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-02-12 01:32

In the first case, you are essentially declaring a private copy constructor and then not providing any implementation. By declaring them private, non-members cannot copy it.

In the second case, the syntax forbids a copy being made. This is C++ native.

The major difference as a programmer is readability and understanding the code. The first case is redundant, why declare the copy constructor, make it private, and not implement it. The client has to infer a lot here.

You can just use "= delete" and clearly imply what you're trying to do.

查看更多
劳资没心,怎么记你
3楼-- · 2019-02-12 01:37

Your first solution conveys to the reader that the copy-constructor is private and is not to be used. Your second solution is only valid in C++11. Because of this, I'd say the more portable and readable implementation would be your first, using the private-property.

查看更多
冷血范
4楼-- · 2019-02-12 01:38

Making it private is the "old" way of doing it. The constructor still exists, but it is private, and can only be invoked from within another class member function.

= delete deletes the constructor. It is not generated by the compiler, and it simply will not exist.

So most likely, = delete is what you want. (although with the caveat that not all compilers support this syntax yet, so if portability is a concern...)

查看更多
Juvenile、少年°
5楼-- · 2019-02-12 01:41

Making a constructor private was basically a "hack" in the old C++, since it was the only way to prevent users from using them. The ability to delete special member functions was only introduced in C++11, and it's the better and more idiomatic way to say that a class cannot be copied. since it is explicit about the intention.

Private constructors have other uses other than forbidding their use entirely (e.g. they may be called by static class member functions). So just making a constructor private doesn't communicate the intention very well, and the resulting error is not very clear, either.

查看更多
兄弟一词,经得起流年.
6楼-- · 2019-02-12 01:42

If you are on C++11, use delete. The reason is that it makes the call explicit and the intent clear. You could still accidentally use a private constructor (e.g. in a restricted set of scopes), but the compiler will forbid you from ever using a deleted constructor.

One issue of the private constructor is that the class and friends can still use it -- this results not in access errors but link errors, which can be hard to trace back to the callsite.

If your necessary toolchains do not support deleted constructors (= delete), you should not define it (as seen in your question) -- only declare it and leave it undefined, e.g.: private: \n Track(const Track&);

查看更多
可以哭但决不认输i
7楼-- · 2019-02-12 01:47

Declaring a copy constructor private still allows member functions of the Track class to copy-construct instances of that class, while making it deleted simply forbids copy-constructing that object.

In C++11, deleting a copy constructor is the right way to express the fact that a class is non-copyable (unless of course it makes sense for you to let member functions of Track, or friends of Track, to copy-construct Track objects).

查看更多
登录 后发表回答