【问题标题】:Can an interface specify only method names, but not return type?接口可以只指定方法名而不指定返回类型吗?
【发布时间】:2011-12-11 01:54:17
【问题描述】:

假设我有一个如下定义的类,例如Value

template <typename T>
class Value : public ValueInterface
{
    public:
        // ...
        T getValue() const;

    private:
        T value_;
}

我是否可以在我的代码中泛指多个不同类型的Values(即具有不同的T 类型)(例如,创建一个容器)?我的第一个想法是是否有可能以某种方式声明一个纯抽象类,Value 可以从中继承:

class ValueInterface
{
    public:
        ?? getValue() const = 0;
}

template <typename T>
class Value : public ValueInterface
{
    // ...
}

std::list<ValueInterface> lst;
Value<int> i(...);
Value<char> c(...);

lst.push_back(i);
lst.push_back(c);

int vi = i.getValue();
char vc = c.getValue();

如果不可能,您能否提供替代解决方案?

【问题讨论】:

  • 您能否给出一个伪代码示例来说明您希望如何使用此类功能?
  • 就在那儿,在第二个 sn-p 中。我需要声明一个std::list 来保存不同的Values。
  • 但这与您的getValue 方法有什么关系?
  • 在您的示例中,您没有以多态方式使用getValue 方法,所以我不确定您为什么要声明它virtual。我也看不出这与容器有什么关系。
  • 您可能会发现boost::any 库很有用。

标签: c++ templates interface polymorphism


【解决方案1】:

在 C++ 中,所有表达式都必须具有编译器已知的类型,但在您的解决方案中 lst.begin()-&gt;getValue() 将没有任何特定类型。

尽管如果您仔细查看您的示例,您并没有在任何地方调用ValueInterface::getValue(),只是子类版本。

您可以尝试以下方法:

class ValueInterface
{
  public:
    template <typename T>
    T getValue() const
    {
        return dynamic_cast< const Value<T> &>(*this).getValue();
    }
    virtual ~ValueInterface()
    { }
};

template <typename T>
class Value : public ValueInterface
{
    public:
        // ...
        T getValue() const;

    private:
        T value_;
};

请注意,getValue() 不是(也不能是)虚拟的。

现在您可以编写示例中的代码,而且:

int z = lst.begin()->getValue<int>();

如果您在 getValue 调用中使用了错误的类型,则会抛出异常 std::bad_cast

【讨论】:

  • 你需要至少一个虚拟函数才能让dynamic_cast 工作。
  • @Xeo 好点。析构函数是这里的最佳选择。已更新。
【解决方案2】:

您不能重载返回类型,因为这会产生各种歧义。

我不太确定你想在这里做什么。我假设您将遍历blah 或从中选择一个随机元素,然后在所述元素上调用getValue()。此调用绝对可以返回任何类型:charconst void*Value&lt; Value&lt; Value&lt;const void*&gt; &gt; &gt; 等。您将如何处理结果?你甚至会如何为它定义一个变量?

【讨论】:

  • 使用 blah 的函数会知道哪些元素返回什么类型,并相应地声明变量。
  • @Dan:如果您对所使用的变量类型有编译时知识,那么您一开始就不需要多态性。
猜你喜欢
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
相关资源
最近更新 更多