我可以根据类声明不同的typedef吗?

时间:2016-06-29 00:29:38

标签: c++ typedef forward-declaration

是否可以根据实例化的派生类来定义不同的类型?

假设我有一个带有虚函数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();};
}

3 个答案:

答案 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中包含的自定义类型不适用于此方法,因为在我们可以专门化模板之前需要声明类型。我在这里使用intdouble是为了方便。根据需要更换。

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中声明类型。根据需要能够查看类型的人员设置访问权限。在这里,我公开Typemain进行测试。类型在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);