如何初始化继承类的静态变量
How to initialize static variable on inherited class?
我正在尝试创建一个"父"类,它为所有继承的类提供通用的构造函数和参数类型。在继承的变量之间唯一发生变化的是一些静态变量的值。
实现这一目标的最佳方法是什么?这是我目前的尝试:
class Ball {
public:
virtual ~Ball();
Ball ();
protected:
static string file;
static int size;
node shape;
};
class TenisBall: public Ball {};
class OtherBall: public Ball {};
Ball::Ball () {
shape = // do something with file and size
};
Ball::~Ball () {
delete shape;
};
string TenisBall::file = "SomeFile";
int TenisBall::size = 20;
string OtherBall::file = "OtherFile";
int OtherBall::size = 16;
我的问题是:我不能在TenisBall
和OtherBall
类上设置静态值,只有当我在最后两行代码中将TenisBall
和OtherBall
更改为Ball
时,编译器才接受。我怎样才能做到这一点?这是最好的方法吗?
编辑:
根据提供的答案,我决定尝试使用虚拟函数来实现它。这是我到目前为止的代码:
class Ball {
public:
Ball () {
shape = // do something with getSize and getFile
};
~Ball () {
delete shape;
};
protected:
virtual string getFile(){ return "Fake"; };
virtual int getSize(){ return 10; };
node shape;
};
class TenisBall: public Ball {
int getSize() { return 16; };
string getFile() { return "TennisBall.jpg"; };
};
int main() {
TenisBall ball;
return 1;
};
但是,虽然我的编辑器(xCode)没有给出任何错误,但在尝试编译时,llvm会给出以下错误:
第22列的Bundle Identifier中的字符"_"无效。此字符串必须是仅包含字母数字(a-Z、a-Z、0-9)、连字符(-)和句点(.)字符的统一类型标识符(UTI)。
您所尝试的是不可能的。一旦在一个类中声明了一个静态变量,这个类就只有一个变量,甚至派生类也不能改变这个变量(所以你不能改变Ball::file
来对TennisBall
做一些不同的事情,不管这意味着什么)。
最简单的解决方法可能是将Ball::file
更改为可以在派生类中重写的虚拟函数(将string
或string&
返回到甚至可以是类或函数静态的东西)。
如果您希望每个派生类都有自己的静态变量,可以将basse类作为模板并使用CRTP:
template<typename T>
class Ball {
static int size;
};
template<typename T> int Ball<T>::size = 0;
class TennisBall : public Ball<TennisBall> {
};
template<> int Ball<TennisBall>::size = 42;
很明显,静态在这里是不允许的,如果你确实使用它们,那么无论你有多少派生类的实例,你都会在内存中有一个数据副本,所以你每次都会覆盖数据。
下面是Ball中处理大小和文件名的一个常见构造函数,怎么样?
class Ball {
public:
virtual ~Ball();
Ball ();
Ball (int curr_size, string curr_filename);
protected:
string file;
int size;
node shape;
};
class TenisBall: public Ball {
TennisBall(int size, string filename)
:this(curr_size, curr_filename)
{
}
};
class OtherBall: public Ball {
OtherBall(int size, string filename)
: this(curr_size, curr_filename)
{
}
};
Ball::Ball () {
shape = // do something with file and size
};
Ball::Ball(int curr_size, string curr_filename) {
shape = // whatever
curr_size = size;
curr_filename = filename;
}
Ball::~Ball () {
delete shape;
};
// ....
Ball *b = new TennisBall(16, "c:/tennisball_photo.jpg");
delete b;
相关文章:
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 模板基类中的静态变量
- 类和静态变量
- 不同作用域中的静态变量和全局变量
- 静态变量声明和定义
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在类中继承静态变量?
- "local scope"中的 C++ 初始化静态变量
- 使用静态变量的递归调用的不同输出
- 复制文件流C++静态变量
- 跨模板化函数编译的静态变量
- C++编译器是否优化了顺序静态变量读取?
- C++,每个循环初始化一个新的静态变量
- (为什么)我们可以在初始化中将非静态类成员分配给静态变量吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- 程序如何知道静态变量是否需要初始化?
- 类外的静态变量实例化
- 无法解析静态变量
- 函数局部静态变量:从性能角度来看的优点/缺点
- 访问从 CPP 文件到其他头文件的静态变量