c++ - 多态类成员变量

标签 c++ oop c++11

我有一个依赖于 printer 实例的类 messengerprinter 是一个多态基类,实际对象在构造函数中传递给 messenger

对于非多态对象,我只需执行以下操作:

class messenger {
public:
    messenger(printer const& pp) : pp(pp) { }

    void signal(std::string const& msg) {
        pp.write(msg);
    }

private:
    printer pp;
};

但是当 printer 是多态基类时,这不再起作用(切片)。

考虑到这一点,最好的方法是什么

  1. 我不想将指针传递给构造函数,并且
  2. printer 类不应需要虚拟 clone 方法(= 需要依赖复制构造)。

我不想将指针传递给构造函数,因为 API 的其余部分使用的是真实对象,而不是指针,并且在这里将指针作为参数会令人困惑/不一致。

在 C++0x 下,我或许可以使用 unique_ptr 和模板构造函数:

struct printer {
    virtual void write(std::string const&) const = 0;
    virtual ~printer() { } // Not actually necessary …
};

struct console_printer : public printer {
    void write(std::string const& msg) const {
        std::cout << msg << std::endl;
    }
};

class messenger {
public:
    template <typename TPrinter>
    messenger(TPrinter const& pp) : pp(new TPrinter(pp)) { }

    void signal(std::string const& msg) {
        pp->write(msg);
    }

private:
    std::unique_ptr<printer> pp;
};

int main() {
    messenger m((console_printer())); // Extra parens to prevent MVP.

    m.signal("Hello");
}

这是最好的选择吗?如果是这样,pre-0x 中最好的方法是什么?有没有办法摆脱构造函数中完全不必要的拷贝?不幸的是,移动临时的在这里不起作用(对吧?)。

最佳答案

没有虚拟克隆方法就无法克隆多态对象。所以你可以:

  • 传递并持有一个引用,并确保打印机在构建 messenger 的代码中的 messenger 之前没有被破坏,
  • 传递并持有一个智能指针并使用 new 创建打印机实例,
  • 传递一个引用并使用克隆方法在堆上创建打印机实例或
  • 将实际类型的引用传递给模板,并在您仍然知道类型的情况下使用 new 创建实例。

最后是你对 C++0x std::unique_ptr 的建议,但在这种情况下,C++03 std::auto_ptr 将完全符合你的要求相同的服务(即您不需要移动它,否则它们是相同的)。

编辑:好的,嗯,还有一种方法:

  • 使 printer 本身成为指向实际实现的智能指针。比它同时具有可复制性和多态性,但代价是一些复杂性。

关于c++ - 多态类成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6096916/

相关文章:

php - 如何在没有子类调用的情况下在父类中自动运行构造

java - 在文本冒险中实现退出

c++ - typedef 模板的成员类型

c++ - 什么时候 `this` 是右值?

android - 我无法将预建库包含到 android studio 中

c++ - 洗牌 QStringList 中的元素

c++ - 没有 typedef 的运算符 member_function_pointer_type()?

c# - 处理数据库时的最佳实践

c++ - 从 constexpr 数组创建可变参数模板

c++ - C++中的单例多线程代码