C ++初始化常量和继承

时间:2010-06-16 23:14:45

标签: c++ inheritance constants

我想在子类而不是基类中初始化常量。并使用它来摆脱动态内存分配(我已经知道数组大小,并且会有一些具有不同常量的子类)。
所以我试试:

class A {
public:
    const int x;

    A() : x(0) {}
    A(int x) : x(x) {}
    void f() {
        double y[this->x];
    }
};

class B : A {
    B() : A(2) {}
};

非常简单,但编译器说:

  

错误C2057:预期的常量表达式

我怎么能对编译器说它真的是常量?

4 个答案:

答案 0 :(得分:4)

虽然不是一个常数。它仍然可以由构造函数修改。对于数组的大小,只允许编译时间常量。当编译器说“常量表达式”时,它并不意味着表达式返回一个常量值,而是一个常量,例如“52”或“45”或沿着这些行的某些东西。

改为使用std::vector

编辑:回应“我已经知道数组大小,并且会有一些具有不同常量的子类”

唯一的方法是使用模板。

template<size_t x>
class A {
public:
    void f() {
        double y[x];
    }
};

typedef A<2> B;

答案 1 :(得分:2)

您可以使用以下模板实现您期望的行为。

请注意,这实际上是不可靠的,令人厌恶的,只能用作“样本”。请改用std::vector

template <size_t a = 0>
class A {
public:
   A() { }

   void f() {
      int y[a];
      y[0] = 5;
   }
};

class B : A<2> {
   B() { }
};

void main() {
   A<1> a;
   a.f();

   // Undefined behaviour - creating an array of size 0
   // At least, MSVS2008 treats it as an error :)
   // A<0> a_;
}

答案 2 :(得分:1)

有“常数”,然后是“常数”。如果你想像这样在堆栈上分配一个数组,编译器需要在编译时获得数组的长度,并且根据你在那里给出的数据,它无法解决这个问题。有趣的是,gcc支持扩展(在标准C ++中不支持),允许为可变长度分配堆栈。

答案 3 :(得分:1)

我不知道它是否适用于您的目的,但一种可能性是将其作为模板参数:

template <int size>
class A { 
    double y[size];
};

在这种情况下,您可能希望在B中创建A的实例而不是使用继承。

另一个明显的可能性是使用tr1::array对象。这也是一个模板,所以这个想法几乎相同,但它已经编写,测试和工作,所以你可以避免这一切。如果你的编译器没有提供TR1类,那么Boost有一个最符合要求的实现(boost::array)。