NonCopyable 不能拷贝的类

chllcy 2012-04-13 08:37:51
  
class NonCopyable
{
private:
NonCopyable(const NonCopyable&); // no implementation
NonCopyable& operator=(const NonCopyable&); // no implementation
public:
NonCopyable() { }
};

对于上面这个设计不是很明白,设计本意应该是不让使用拷贝构造函数和=赋值操作.但我下面这个还是可以啊
 
class DD:private NonCopyable
{
private:
int a;
public:

DD(){a=0;}
DD(int xx):a(xx){};
DD(const DD& xx){a=xx.a;}
DD& operator=(const DD& xx){a=xx.a;}
virtual ~DD(){};
void getA(){cout <<"a:"<< a << endl;};
};

DD xx,yy(1);
NonCopyable cc;
xx.getA();
xx=yy;
xx.getA();
cc=xx;//不行

只是对于cc=xx不行,但对于xx=yy还是可以的.不知道NonCopyable这个类的设计本意是什么.
...全文
169 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hemmingway 2012-07-17
  • 打赏
  • 举报
回复
发现自己很菜鸟了
FrankHB1989 2012-04-14
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

引用 7 楼 的回复:

大哥,
注释掉xx=yy就不报错了.为什么?
既然默认会添加拷贝构造函数,则DD的拷贝构造函数应该会去调用NonCopyable的拷贝构造函数,此处应该会报错.

"拷贝构造函数应该会去调用"?
下面两种情况会:
1> 子类没实现对应"拷贝"时; (去掉Derive中的"拷贝"看看)
2> 子类中显式调用了父类的对应"拷贝"时;(Derive"拷贝"……
[/Quote]
其实是一回事。如果没有显式定义,那么隐式生成的非deleted定义需要基类可以复制构造。
“没实现”过于笼统,而“别的情况不会”过于武断。
C++11的Base(const Base&) = delete;看来不能称为用户提供的实现(但很明确,它是定义)。这应该是当前实现LZ需求的最明确的做法(当然考虑C++98/03兼容性就没办法了)。

ken_scott 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

大哥,
注释掉xx=yy就不报错了.为什么?
既然默认会添加拷贝构造函数,则DD的拷贝构造函数应该会去调用NonCopyable的拷贝构造函数,此处应该会报错.
[/Quote]
"拷贝构造函数应该会去调用"?
下面两种情况会:
1> 子类没实现对应"拷贝"时; (去掉Derive中的"拷贝"看看)
2> 子类中显式调用了父类的对应"拷贝"时;(Derive"拷贝"中加上Base对应"拷贝"看看)
别的情况不会

#include <iostream>
using namespace std;

class Base
{
public:
Base()
{
cout << "Base()" << endl;
}
Base(const Base &)
{
cout << "Base(const Base &)" << endl;
}
Base & operator = (const Base &)
{
cout << "Base & operator = (const Base &)" << endl;
return (*this);
}
};

class Derive : private Base
{
public:
Derive()
{
cout << "Derive()" << endl;
}
Derive(const Derive &)
{
cout << "Derive(const Derive &)" << endl;
}
Derive & operator = (const Derive &)
{
cout << "Derive & operator = (const Derive &)" << endl;
return (*this);
}
};

int main() {
Derive d1;
Derive d2(d1);
Derive d3;
d3 = d1;
return 0;
}
ken_scott 2012-04-13
  • 打赏
  • 举报
回复

如果我们想让DD(别的类也是一样)不能被拷贝, 一般会这么写:
class DD
{
// ...
private:
DD(const DD &);
DD & operator = (const DD &);
}
但这样写很麻烦, 因为我们得在每个有这种要求的类中都要写:
private:
XX(const XX &);
XX & operator = (const XX &);
所以就想到写个基类NonCopyable来做这个事, 这样我们就可以简写成:
class DD : public NonCopyable /* public("是一种"的关系, 而不是"有一个"的关系) */
{
// ...
/* 下面的不需要了 *
/*
private:
DD(const DD &);
DD & operator = (const DD &);
*/
}

但, LZ却又实现并提供(public)了子类的拷贝接口, 它当然可以拷贝了

LZ弄错前因后果了 ^_^
chllcy 2012-04-13
  • 打赏
  • 举报
回复
大哥,
注释掉xx=yy就不报错了.为什么?
既然默认会添加拷贝构造函数,则DD的拷贝构造函数应该会去调用NonCopyable的拷贝构造函数,此处应该会报错.
chllcy 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
引用 4 楼 的回复:
如果默认会添加的话 为什么编译阶段不报错呢?
只有在执行xx=yy;时才报错呢?

我编译报错了。。
是指编译到xx=yy这行报错的
[/Quote]
对,但是注释掉xx=yy就不报错了.这个是为什么?
如果默认添加的话,DD里的生成的默认构造函数会调用NonCopyable里的默认构造函数?此处应该报错的.
evencoming 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
如果默认会添加的话 为什么编译阶段不报错呢?
只有在执行xx=yy;时才报错呢?
[/Quote]
我编译报错了。。
是指编译到xx=yy这行报错的
chllcy 2012-04-13
  • 打赏
  • 举报
回复
如果默认会添加的话 为什么编译阶段不报错呢?
只有在执行xx=yy;时才报错呢?
evencoming 2012-04-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
知道为什么那么多类继承NonCopyable了,因为不写
DD(const DD& xx){a=xx.a;}
DD& operator=(const DD& xx){a=xx.a;}
C++ 会默认添加这两个方法,现在继承了NonCopyable,则在不手动添加这两个方法的时候 DD的拷贝构造函数和赋值操作都是非法的.

不知道C++是否会默认添加DD的……
[/Quote]
会.然后调用std::move。
但是因为无法复制NonCopyable,所以报错
chllcy 2012-04-13
  • 打赏
  • 举报
回复
知道为什么那么多类继承NonCopyable了,因为不写
DD(const DD& xx){a=xx.a;}
DD& operator=(const DD& xx){a=xx.a;}
C++ 会默认添加这两个方法,现在继承了NonCopyable,则在不手动添加这两个方法的时候 DD的拷贝构造函数和赋值操作都是非法的.

不知道C++是否会默认添加DD的拷贝构造函数和赋值操作??

evencoming 2012-04-13
  • 打赏
  • 举报
回复
你都提供
DD& operator=(const DD& xx){a=xx.a;}了。
自然可以。
如果你不提供的时候,
class DD
{
NonCopyable no;
public:
...

};
这样就没发复制了。

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧