c++ - 为不可复制对象选择构造函数

标签 c++ boost noncopyable multiple-constructors

假设我有一个不可复制的类,它有多个这样的构造函数

class Foo: boost::noncopyable
{
  public:
    Foo(std::string s) {...};  // construct one way        
    Foo(int i) {...};  // construct another way
 }

现在,我要构造一个对象,并选择在运行时使用哪个构造函数:

我可以用这样的指针来做:-

boost::shared_ptr<Foo> f;

if (condition)
  f.reset(new Foo(myString));
else
  f.reset(new Foo(myInteger));

// common code follows
f->doSomethingComplicated(...);

但这感觉很困惑而且很慢。有没有一种简单的方法来为对象选择构造函数而不诉诸动态分配?


更多细节:上面的Foo类只是为了说明问题。实际涉及的类是Windows Gdiplus::Bitmap - http://msdn.microsoft.com/en-gb/library/windows/desktop/ms534420(v=vs.85).aspx

最佳答案

您可以在堆栈上使用 C++11 来执行此操作,无需放置 new 且无需复制/移动构造函数/赋值。观察:

auto factory = [&]() -> Foo 
{ 
  if (condition) {
    return { myString };
  } else {
    return { myInteger };
  }
};
Foo&& foo = factory();
foo.doSomethingComplicated();

仿函数和 Foo 实例将在堆栈上愉快地生活,不进行任何分配(可能除了在 Foo 的构造函数中复制字符串)。 Foo 超出范围时将调用其析构函数。赢了。

使用统一初始化构造返回值时,不涉及复制/移动操作。请注意,返回 myString (隐式转换)或 Foo(myString) 将强制编译器检查对象是否可复制/可移动,即使这样的拷贝/move 可以省略。

编辑:或者,这可以更短,但更“神奇”:

Foo&& foo = [&]() -> Foo 
{ 
  if (condition) {
    return { myString };
  } else {
    return { myInteger };
  }
}();

编辑:C++11 之前,Visual Studio hacky 解决方案:

在使用隐式转换构造函数从函数返回值时,VC 似乎不检查对象是否可复制。所以这是有效的,即使它违反标准:

Foo make_foo(bool condition, const std::string&s, int i)
{
    if ( condition) {
        return s;
    } else {
        return i;
    }
}

然后就这样使用它:

Foo& f = make_foo(condition, myString, myInteger);

请注意,这是另一个 VC hack,因为根据标准临时不能分配给对可变对象的引用,即它需要更改 const Foo&,这将是这里相当有限。

不是说你应该这样处理,但这是可能的。

关于c++ - 为不可复制对象选择构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23933024/

相关文章:

c++ - 最快的 SHA1 实现是什么?

c++ - 可以将容器的复制构造函数定义为不可复制值类型的删除吗?

c++ - 在从 Boost 派生的类派生的类中自动禁止复制是不可复制的吗?

c++ - 如何使映射键具有两种不同的数据类型?

c++ - 在模板中使用模板实例类型

c++ - 为什么我的编译器不能识别 #include <thread> (c++)?

c++ - boost::unordered_map 可以与 std::shared_ptr 一起使用吗?

c++ - 将 XCode 项目动态链接到 lib4cxx 库时,如何解决单个符号链接(symbolic link)错误?

c++ - boost foreach 和运算符重载

C++ optional<> 和不可复制对象的延迟构造