是否可以根据实例化的派生类来定义不同的类型?
假设我有一个带有虚函数func()
的父类,两个int成员和一个类型为myType
的向量,以及两个子类,它们共享相同的int成员和向量,但是他们对func()
的实施要求myType
略有不同。
例如:
class Parent {
protected:
int myMember;
int myOtherMember;
std::vector<myType> vec;
public:
Parent(variable);
virtual int func() = 0;
}
class Child1 : public Parent {
private:
typedef <some type definiton> myType;
public:
Child1(variable) : Parent(variable){};
int func() {return someFunc();};
}
class Child2 : public Parent {
private:
typedef <some other type definiton> myType;
public:
Child2(variable) : Parent(variable){};
int func() {return someOtherFunc();};
}
我可以这样做吗?当我尝试它时,它会在头文件中创建一个循环依赖,因为首先需要包含类Parent
,但是它需要定义myType
。
有没有办法根据课程声明myType
?或者我只需要在每个类中包含myType
的不同向量,如下所示:
class Parent {
protected:
int myMember;
int myOtherMember;
public:
Parent(variable);
virtual int func() = 0;
}
class Child1 : public Parent {
private:
typedef <some type definiton> myType;
std::vector<myType> vec;
public:
Child1(variable) : Parent(variable){};
int func() {return someFunc();};
}
class Child2 : public Parent {
private:
typedef <some other type definiton> myType;
std::vector<myType> vec;
public:
Child2(variable) : Parent(variable){};
int func() {return someOtherFunc();};
}
答案 0 :(得分:3)
这是template
男人的工作!
首先我们声明父
template <class TYPE>
class Parent {
protected:
int myMember;
int myOtherMember;
std::vector<TYPE> vec;
public:
Parent(TYPE variable);
virtual int func() = 0;
};
不幸的是,Child1
中包含的自定义类型不适用于此方法,因为在我们可以专门化模板之前需要声明类型。我在这里使用int
和double
是为了方便。根据需要更换。
using Child1Type = int;
// or typedef int Child1Type; pre-C++11
class Child1 : public Parent<Child1Type> {
public:
Child1(Child1Type variable) : Parent(variable){};
int func() {return someFunc();};
};
using Child2Type = double;
class Child2 : public Parent<Child2Type> {
public:
Child2(Child2Type variable) : Parent(variable){};
int func() {return someOtherFunc();};
};
踢我自己因为没有早点得到这个(并且因为我知道它必须是可能的,所以燃烧的方式太多了,但是却想错了方向)
在Parent中声明类型。根据需要能够查看类型的人员设置访问权限。在这里,我公开Type
在main
进行测试。类型在Parent
中声明,并且可以看到(并且通过,因为它是public
)子项。
还删除了一些不是立即需要的东西,并使用了固定宽度的整数类型,这样我就可以很容易地证明这些差异。
我认为这正是Pixelchemist所暗示的。
template <class TYPE>
class Parent {
public:
using Type = TYPE; // declare Type here
protected:
int myMember;
int myOtherMember;
std::vector<Type> vec; // visible here
public:
Parent(Type variable); // here
virtual ~Parent(){}
virtual int func() = 0;
};
class Child1 : public Parent<uint16_t> { // complicated type needs to be reproduced
// only once, here in the specialization
public:
Child1(Type variable) : Parent(variable){};
};
class Child2 : public Parent<uint32_t> {
public:
Child2(Type variable) : Parent(variable){};
};
int main()
{
// and visible way down here in main through Child1 and Child2
std::cout << "Child 1: " << sizeof(Child1::Type) << std::endl;
std::cout << "Child 2: " << sizeof(Child2::Type) << std::endl;
}
输出
Child 1: 2
Child 2: 4
答案 1 :(得分:1)
您可以简单地使用模板:
template<class T>
struct Base
{
std::vector<T> v;
};
struct D1 : public Base<int>
{
// all stuff in here comes into play when deriving from Base is already done
// Thus, compiler cannot know any typedefs from here inside Base...
};
struct D2 : public Base<double>
{
};
您不能在基类中使用派生的typedef。请参阅 CRTP refer to typedef in derived class from base class 。
答案 2 :(得分:0)
这是模板的用途:
<template typename T>
class Child : public Parent {
private:
std::vector<T> vec;
public:
Child(variable) : Parent(variable) {};
int func() { return someOtherFunc(); };
}
然后将Child
声明为:
Child<int> myChildInstance(10);