我有一个抽象基类和一对从这个基类派生的类。我想介绍一个static const
成员,它在两个派生类之间具有不同的值,但对于给定派生类的所有实例具有相同的值。
我的代码使用分配给两个派生类之一的实例的基类指针,这样我就可以通过更改基类指针的分配来轻松地在派生类之间切换。我希望能够以类似的方式使用基类获取派生类的常量值的值,以便我可以在两个类之间轻松切换。期望的行为如下所示:
#include <iostream>
using namespace std;
// Abstract base class
class A {
protected:
int c; // this is really a constant and should also be static
public:
static int s;
int get_c() const {
return this->c;
}
virtual int foo() = 0; // makes this class abstract
};
class B : public A {
public:
static const int sb = 10;
B() {
this->c = 1;
}
int foo() {
return -1;
}
};
class C : public A {
public:
static const int sc = 20;
C() {
this->c = 2;
}
int foo() {
return -2;
}
};
int main() {
B btest;
C ctest;
A *ptr = &btest; // pointer to instance of B
//cout << ptr->c << endl; // would fail compilation (c is protected)
cout << "B's c = " << ptr->get_c() << endl;
cout << "B's foo() returns " << ptr->foo() << endl;
cout << "Accessing B's static const member: " << B::sb << endl;
ptr = &ctest; // pointer to instance of C
//cout << ptr->c << endl; // would fail compilation (c is protected)
cout << "C's c = " << ptr->get_c() << endl;
cout << "C's foo() returns " << ptr->foo() << endl;
cout << "Accessing C's static const member: " << C::sc << endl;
return 0;
}
在上面的代码中,sb
和sc
是我想要的static const
成员,但问题是基类A
不知道它们。基类成员c
正在按我的意愿行事,但不是static const
所需(我已c
成为protected
成员,因此无法修改,但如果我可以声明const
然后它可以是public
)。此代码具有c
:
c
的不同值。c
实际上是常量,因为它是protected
而我没有提供setter函数。但是,c
不是真正的常量,因为它不是const
而且它不是static
所以每个实例都有一个不必要的副本它的。
有没有办法获得所需的行为,并且c
与static const
sb
和sc
一起声明{{1}}?
答案 0 :(得分:4)
您无法在A
中使用静态变量实现此功能;这对于A
的所有子类型都是通用的,因此您无法为每个子类型获取不同的值。由于基类指针后面的对象的动态类型仅在运行时已知,因此您需要一个运行时机制来从中获取值。
这可以使用每个对象变量,如果你在构造函数中初始化它可以是const
:
class A {
// ...
const int c;
A(int c) : c(c) {}
};
class B : public A {
// ...
B() : A(1) {}
};
class C : public A {
// ...
C() : A(2) {}
};
或每个子类重写的虚函数返回不同的值:
class A {
// ...
int get_c() const = 0;
};
class B : public A {
// ...
int get_c() const {return 1;}
};
class C : public A {
// ...
int get_c() const {return 2;}
};
这两个选项都符合您的要求;一个具有访问虚拟函数调用的成本,而另一个具有每个对象变量的成本。您必须决定哪种费用更适合您的需求。