Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;不可复制,有时除外_C++_Noncopyable - Fatal编程技术网

C++ C++;不可复制,有时除外

C++ C++;不可复制,有时除外,c++,noncopyable,C++,Noncopyable,我发现使类不可复制对我的代码质量有很大帮助。起初,我使用boost::noncopyable执行此操作,但我发现VC++编译器错误没有私有成员那么有用(双击会导致代码中的错误位置) 事实上,它提醒了我,有相当多的情况是类没有作为引用传递到它们应该传递的地方。如此之多,以至于我非常希望得到一个警告,即使是在我只需要复制一次构造的类上 有什么好办法吗?例如,我考虑将上述两个方法保留为私有,并添加一个公共的T(T const&,bool dummy)构造函数,以便在我真正想要复制构造时调用。或者,也可

我发现使类不可复制对我的代码质量有很大帮助。起初,我使用boost::noncopyable执行此操作,但我发现VC++编译器错误没有私有成员那么有用(双击会导致代码中的错误位置)

事实上,它提醒了我,有相当多的情况是类没有作为引用传递到它们应该传递的地方。如此之多,以至于我非常希望得到一个警告,即使是在我只需要复制一次构造的类上

有什么好办法吗?例如,我考虑将上述两个方法保留为私有,并添加一个公共的T(T const&,bool dummy)构造函数,以便在我真正想要复制构造时调用。或者,也可以将上述两个方法公开,并在复制构造时以某种方式激活编译器警告,在我希望的地方抑制警告


或者也许有一个更好的方法?

我想你自己也提出了一个完美的方法

我刚刚想起我曾经在另一个代码库中玩过的一个巧妙的小把戏:

struct T
{
    friend class SomeClientThatCanConstructT;
    T(T const&);

  private:
     T(T const&);           
};

正如评论中所讨论的,以下内容将不适用

您可以选择显式名称(如CopyConstruct)并依赖RVO来实现同样的效率:

struct T
{
     inline T CopyConstruct() const     { return *this; }
     inline T& AssignTo(T& dst) const   { return dst = *this; }
     inline T& AssignFrom(const T& src) { return *this = src; }

  private:
     T(T const&);
     T& operator=(T const&);
};

您可以默认构造一个
T
,然后添加一个
assign
方法来使用。不过,这似乎不是完全最优的,这表明您可能希望查看您的复制需求。

不确定它是否正是您想要的,但是如果您将复制构造函数标记为显式的,则类不能通过值传递或复制初始化,但您可以使用直接初始化来复制构造


您可能希望将赋值运算符保持为私有,可能一个
不可分配的
基会对此很有用。

我不喜欢限制类型的想法(
CopyConstructible
在stdlib中是一个广泛使用的概念),因为它可能被误用。如果可以从另一个实例构造对象,那么它应该是可复制构造的。它还分散了读者对重要代码的注意力,而没有达到任何真正的目的


也许在调试模式下,复制构造函数触发的警告或断言才是您真正想要的?

我考虑过这一点,但您的
CopyConstruct
要求即使编译器不调用它,也可以访问复制构造函数。Shute。谢谢你提醒我。这确实是一个阻碍。当然,您可以一路丑化它,但是对于构造函数调用,您的“标记参数”解决方案真的没有其他选择。回想起来,我突然想起自己做过这件事。。。更新回答为什么需要
私人标签
?friend类不能直接调用私有副本构造函数吗?@Nemo:我记错了。显然一个人可能太忙了,所以。。。我在旧的代码库中找到了这一点,结果证明,在将类迁移为单例时,我只是使用标记来检测默认构造函数的长期使用。我不知道为什么我会得出这样的结论:我最喜欢这个答案。根据我的经验,复制构造函数的问题是当它们在某个大型对象上被“意外”调用时<代码>显式强制您在调用它们时考虑它,这应该足够了。干杯,这非常适合我的需要。谢谢。有这样的东西吗?e、 当编译器或链接器链接到函数时,我是否可以定义一个用户定义的警告?然后抑制我想要的对象文件中的警告?像一个pragma警告?
struct T
{
     inline T CopyConstruct() const     { return *this; }
     inline T& AssignTo(T& dst) const   { return dst = *this; }
     inline T& AssignFrom(const T& src) { return *this = src; }

  private:
     T(T const&);
     T& operator=(T const&);
};