禁用复制构造函数

发布于 2024-11-09 11:13:54 字数 489 浏览 0 评论 0原文

我有一个类:

class SymbolIndexer {
protected:
  SymbolIndexer ( ) { }

public:
  static inline SymbolIndexer & GetUniqueInstance ( ) 
  { 
    static SymbolIndexer uniqueinstance_ ;
    return uniqueinstance_ ; 
  }
};

我应该如何修改它以禁用如下代码:

SymbolIndexer symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

并仅允许如下代码:

SymbolIndexer & ref_symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

I have a class:

class SymbolIndexer {
protected:
  SymbolIndexer ( ) { }

public:
  static inline SymbolIndexer & GetUniqueInstance ( ) 
  { 
    static SymbolIndexer uniqueinstance_ ;
    return uniqueinstance_ ; 
  }
};

How should I modify it to disable code like:

SymbolIndexer symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

and only allow code like:

SymbolIndexer & ref_symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

早乙女 2024-11-16 11:13:54

您可以将复制构造函数设为私有并且不提供任何实现:

private:
    SymbolIndexer(const SymbolIndexer&);

或者在 C++11 中明确禁止它:

SymbolIndexer(const SymbolIndexer&) = delete;

You can make the copy constructor private and provide no implementation:

private:
    SymbolIndexer(const SymbolIndexer&);

Or in C++11, explicitly forbid it:

SymbolIndexer(const SymbolIndexer&) = delete;
爱你是孤单的心事 2024-11-16 11:13:54

如果您不介意多重继承(毕竟,这并没有那么糟糕),您可以使用私有复制构造函数和赋值运算符编写简单的类,并另外对其进行子类化:

class NonAssignable {
private:
    NonAssignable(NonAssignable const&);
    NonAssignable& operator=(NonAssignable const&);
public:
    NonAssignable() {}
};

class SymbolIndexer: public Indexer, public NonAssignable {
};

对于 GCC,这会给出以下错误消息:

test.h: In copy constructor ‘SymbolIndexer::SymbolIndexer(const SymbolIndexer&)’:
test.h: error: ‘NonAssignable::NonAssignable(const NonAssignable&)’ is private

我不是很不过,这肯定适用于每个编译器。有一个相关问题,但尚未得到答案。

UPD:

在 C++11 中,您还可以编写 NonAssignable 类,如下所示:

class NonAssignable {
public:
    NonAssignable(NonAssignable const&) = delete;
    NonAssignable& operator=(NonAssignable const&) = delete;
    NonAssignable() {}
};

delete 关键字可防止默认构造成员,因此它们不能在派生类的默认构造成员中进一步使用。尝试分配会在 GCC 中出现以下错误:

test.cpp: error: use of deleted function
          ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
test.cpp: note: ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
          is implicitly deleted because the default definition would
          be ill-formed:

UPD:

Boost 已经有一个用于相同目的的类,我猜它甚至以类似的方式实现。该类名为 boost: :noncopyable 的用途如下:

#include <boost/core/noncopyable.hpp>

class SymbolIndexer: public Indexer, private boost::noncopyable {
};

如果您的项目策略允许,我建议坚持使用 Boost 的解决方案。另请参阅另一个boost::noncopyable相关问题了解更多信息。

If you don't mind multiple inheritance (it is not that bad, after all), you may write simple class with private copy constructor and assignment operator and additionally subclass it:

class NonAssignable {
private:
    NonAssignable(NonAssignable const&);
    NonAssignable& operator=(NonAssignable const&);
public:
    NonAssignable() {}
};

class SymbolIndexer: public Indexer, public NonAssignable {
};

For GCC this gives the following error message:

test.h: In copy constructor ‘SymbolIndexer::SymbolIndexer(const SymbolIndexer&)’:
test.h: error: ‘NonAssignable::NonAssignable(const NonAssignable&)’ is private

I'm not very sure for this to work in every compiler, though. There is a related question, but with no answer yet.

UPD:

In C++11 you may also write NonAssignable class as follows:

class NonAssignable {
public:
    NonAssignable(NonAssignable const&) = delete;
    NonAssignable& operator=(NonAssignable const&) = delete;
    NonAssignable() {}
};

The delete keyword prevents members from being default-constructed, so they cannot be used further in a derived class's default-constructed members. Trying to assign gives the following error in GCC:

test.cpp: error: use of deleted function
          ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
test.cpp: note: ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
          is implicitly deleted because the default definition would
          be ill-formed:

UPD:

Boost already has a class just for the same purpose, I guess it's even implemented in similar way. The class is called boost::noncopyable and is meant to be used as in the following:

#include <boost/core/noncopyable.hpp>

class SymbolIndexer: public Indexer, private boost::noncopyable {
};

I'd recommend sticking to the Boost's solution if your project policy allows it. See also another boost::noncopyable-related question for more information.

書生途 2024-11-16 11:13:54

SymbolIndexer( const SymbolIndexer& ) 设为私有。如果您分配给参考,那么您就不是在复制。

Make SymbolIndexer( const SymbolIndexer& ) private. If you're assigning to a reference, you're not copying.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文