重写派生类中的模板基方法?
overriding the template base method in derived class?
>假设我有一个基类,如下所示:
template <typename T>
class Base {
// implementation
void do_something() { /* ... */ } ;
};
然后,我创建一个Derived
类,如下所示,并覆盖do_something()
方法:
template <typename T>
class Derived : public Base<T> {
// implementation
void do_something() { /* ... */ } ;
};
我知道虚拟化在类模板中不起作用,我只是隐藏了方法的实现。 但我确实想将一堆派生类和基类存储到一个向量中,(我不想使用类型擦除或多态性),
我的问题是,鉴于Derived
类到基类的static_cast
给了我基于类的do_something
,有什么方法可以将它们存储为基类,而每个类都有do_something()
类的实现?
但我确实想将一堆派生类和基类存储到一个向量中,(我不想使用类型擦除或多态性),
这在C++已经是不可能的。在C++中,向量只能包含相同静态类型的对象。矢量可以包含不同类型的对象的唯一方法是它们的静态类型仍然相同,但它们具有不同的动态类型,但这是您说不想使用的类型擦除/多态性。
我认为也许你需要重新考虑你的要求,因为你的问题本质上是:我想做某事,但我不想使用技术X,它被明确定义为在C++中做某事的唯一方法!
我这样做了,它似乎工作正常:
#include <iostream>
template <typename T>
struct Base {
virtual void do_something() { std::cout << "Base::do_something()n"; }
};
template <typename T>
struct Derived : public Base<T> {
virtual void do_something() { std::cout << "Derived::do_something()n"; }
};
int main() {
Base<int> b;
Derived<int> d;
Base<int> *p;
p = &b;
p->do_something();
p = &d;
p->do_something();
return 0;
}
输出:
Base::do_something()
Derived::do_something()
melpomene答案的一点变化(为Base<T>
结构添加一个无模板的基本结构,BaseOfBase
)允许使用不同T
类型的派生类的基的通用向量。
一个工作示例
#include <vector>
#include <iostream>
struct BaseOfBase
{ virtual void do_something () = 0; };
template <typename T>
struct Base : public BaseOfBase
{
T val;
void do_something ()
{ std::cout << "Base::do_something() [" << val << "]n"; };
};
template <typename T>
struct Derived : public Base<T>
{ void do_something()
{ std::cout << "Derived::do_something() [" << this->val << "]n"; } };
int main ()
{
std::vector<BaseOfBase*> vpbb;
Base<int> bi;
Derived<int> di;
Base<std::string> bs;
Derived<std::string> ds;
bi.val = 1;
di.val = 2;
bs.val = "foo";
ds.val = "bar";
vpbb.push_back(&bi);
vpbb.push_back(&di);
vpbb.push_back(&bs);
vpbb.push_back(&ds);
for ( auto const & pbb : vpbb )
pbb->do_something();
}
当我们说虚拟化在模板类中不起作用时,我们并不是说你不能在模板类中执行虚函数,也不意味着你不能用它的专用版本覆盖成员函数。
@melpomene展示了一个一般覆盖的示例,我将在这里专门展示:
#include <iostream>
template <typename T>
class Base {
public:
virtual T do_something(T in) { std::cout << "Base::do_something()n"; return in; }
};
class Derived : public Base<int> {
public:
virtual int do_something(int in) { std::cout << "Derived::do_something()n"; return in - 1; }
};
void main()
{
Base<int> b;
Derived d;
Base<int> *p = &b;
auto r1 = p->do_something(10);
std::cout << r1 <<std::endl;
p = &d;
auto r2 = p->do_something(10);
std::cout << r2 << std::endl;
}
哪个将输出
Base::do_something()
10
Derived::do_something()
9
表明它完美地按预期工作。
我们这么说是什么意思
虚拟化在类模板中不起作用
基本上意味着当需要基时,您不能将派生类用作模板。
考虑上面的类Base<T>
和Derived
,那么如果我们有以下代码:
#include <memory>
template <typename T>
void Test(std::unique_ptr<Base<T>> in){ std::cout << "This will not work with derived"; }
void main()
{
Base<int> b;
Derived d;
auto ptr = std::unique_ptr<Derived>(&d);
Test(ptr); // <-- Will fail to compile as an invalid argument
}
它将失败,因为std::unique_ptr<Derived>
不会从std::unique_ptr<Base<T>>
继承,尽管Derived
本身继承自Base<T>
。
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 为什么此派生对象无法访问基类的后递减方法?
- 是否可以为 QPixmap 派生类嵌入缩放方法?
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 使用基类中的派生方法运行线程,而无需使用模板
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?
- 在派生类中使用基类的私有成员变量的最佳方法
- 如何在从抽象基派生的类中实现相同的方法?
- 调用从模板派生的类的静态方法,而不指定模板
- 如何在工厂方法中返回指向基于基础操作系统的派生类的有效指针
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 从基类实例调用派生类方法而不进行强制转换
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- C ++基础私有方法在将自身转换为派生类后可以访问吗?
- C++ 使用派生类方法更改基类数据成员
- 如何使用派生类特定的方法:派生类中的派生成员
- 使用抽象类的指针访问派生类的方法;派生类似乎也是抽象的