【问题标题】:C++ Abstract Base Template Class Non-Void MethodC++ 抽象基模板类非 Void 方法
【发布时间】:2017-03-22 06:48:12
【问题描述】:

我有一个包含成员函数的抽象基模板类,其中一些是 void,另一些则返回从原始数据类型到模板参数数据类型的数据类型。我还是 C++ 新手,我知道我不一定要在基类中实现纯虚函数,除非我希望在派生类中调用它们。这个想法适用于没有返回值的成员函数。对于一个返回整数的函数,我返回了一个 0。但是当我到达一个返回对 T(模板参数)的引用的函数时,我不知道该怎么办。我尝试了以下两个返回。

template <typename T>
T& AbstractBaseClass<T>::function(){
return T();
}

template <typename T>
T& AbstractBaseClass<T>::function(){
return T& tmp= T();
}

但两者似乎都不起作用,我不能不定义这些函数,因为我得到了一个未定义的函数引用错误。我认为这个错误是因为函数是模板。实现非 void 纯虚函数的合适方法是什么?

template <typename T>
class AbstractBaseClass{
public:
virtual ~AbstractBaseClass() = 0;
T& function();
}

template <typename T>
T& AbstractBaseClass<T>::function(){
    //what must I do here when I don't have any member variable
}

【问题讨论】:

  • 问题是你试图返回一个对 temporary 对象的引用。想一想当该临时对象被破坏(立即)时会发生什么,那么引用将引用什么?
  • 抽象基类可能没有成员变量,但你的具体派生类肯定需要一个。
  • @Someprogrammerdude 因此,我在源文件中的函数头应该是“virtual T& AbstractBaseClass::function()=0”?我无法这样做,因为我收到一条错误消息,提示“模板可能不是‘虚拟’”
  • 叹息。 “当我没有任何成员变量时我必须在这里做什么”的答案是返回一个局部静态变量,返回一个全局变量,或者几乎,你不能。阅读右值、左值、临时值和引用。
  • 删除整个template &lt;typename T&gt; T&amp; AbstractBaseClass&lt;T&gt;::function(){}部分,你不需要它。

标签: c++ templates pure-virtual


【解决方案1】:

这是一个纯虚函数和实现它的派生类的示例(为清楚起见,省略了一些成员函数):

template <class T>
class Base
{
   public:
     virtual T& get() = 0;
     virtual ~Base() = 0;
};

template <class T>
Base<T>::~Base() {}

template <class T>
class Derived: public Base<T>
{
   T t;
   public:
     T& get() override { return t; }
};

注意Base 中的get() 没有实现,Derivedget 的实现使用了Base 中不可用的新数据成员。

还要注意,纯虚析构函数,与其他纯虚函数不同,必须有一个实现。通常,如果类中有其他纯函数,则不需要纯虚析构函数。此处显示是为了说明。

【讨论】:

  • 假设 get() 既不是纯虚函数也不是虚函数,它需要提供一个实现。如果 Base 类中不存在成员变量,get() 的基类实现如何返回对 T 的引用?
  • @Skipher 这样的函数不能定义,这没关系,因为定义它们没有意义。
  • @Skipher 不会。如果它不是虚函数,那么它在基类中有一个实现。要返回基类中的引用,它需要基类中的成员变量(或全局变量,或非临时变量)。
  • @n.m.but 看来我必须定义它,因为编译器告诉我“在返回非 void 的函数中没有返回语句”。
  • @Skipher。让我们再试一次。如果您需要派生类将实现的函数,请将其设为纯虚拟并且不要在基类中提供实现。如果你想在基类中实现一个函数,它必须只在基类的上下文中有意义,而不考虑任何派生类。您的基类函数应该做什么?如果你不能解释,这个功能就没有存在的理由。
猜你喜欢
  • 2011-06-12
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多