为了让事情尽可能简单,我想构建一个带有静态数组的类。在程序的整个生命周期中声明一次并在类的所有实例之间共享的数组。
作为上述问题的扩展,我想知道是否有可能形成一个继承层次结构,这样孩子们就会有来自父母的不同(静态)数组。
最后,如果可能的话,我希望能够在我的类的头文件中声明这些数组。
单独这些任务看起来似乎很合理,但如果合并后我对我如何编写代码感到非常难过,我们将非常感谢您提供的任何帮助,并提前感谢。
修改
在头文件中:
class A {
public:
static int[] arr;
static int arrLength;
};
class B : A {
public:
static int[] arr = {1, 2, 3}
static int arrLength = 3;
};
其中A仅用作层次结构的根,并且用于其他不相关的属性和函数的某种程度的多态性。
答案 0 :(得分:1)
静态数据成员不能被继承,所以我认为没有机会用普通的子类化/继承来做这件事。您宁愿对此层次结构进行编码,例如通过引入一个以类名作为键的地图。
我看到一个(丑陋)"解决方案"通过滥用模板,它是如此丑陋,我想与你分享:-)。 它利用了这样一个事实:模板类在参数化/实例化时会为不同类型产生不同的类。这也适用于他们的静态数据成员:
template<typename T = char[100]>
class MyClass {
public:
static T val;
};
template<typename T>
T MyClass<T>::val = "";
class Derived1 : public MyClass<char[101]> {
};
class Derived2 : public MyClass<char[102]> {
};
int main() {
Derived1 c1;
Derived2 c2;
Derived2 c2_2;
strcpy(c1.val, "Herbert");
strcpy(c2.val, "Anton");
cout << c1.val << " " << c2.val << " " << c2_2.val << endl;
}
输出显示Derived2
- 实例共享一个公共值,而Derived1
- 实例有自己的实例:
Herbert Anton Anton
明显的缺点是你必须为每个子类引入一个不同的类型(即char[101], char[102],...
;否则它不会产生不同的类,你将再次共享一个公共的静态变量。所以
class Derived1 : public MyClass<char[101]> { ... }
class Derived2 : public MyClass<char[101]> { ... }
会产生输出,即使Derived1
和Derived2
- 实例共享静态数据成员val
的相同值:
Anton Anton Anton
这就是为什么它不仅丑陋而且不实用。
使用&#34;普通&#34;如引言中所提到的,继承将无济于事,因为静态数据成员在某种程度上等同于&#34; global&#34;各个类的命名空间中的变量。所以它们不是继承的,但是你必须为每个子类定义这样一个变量。并且,由于静态数据成员没有继承,因此没有动态绑定:
class Base {
public:
static char v[100];
};
char Base::v[100];
class Derived_1 : public Base {
public:
static char v[100];
};
char Derived_1::v[100];
class Derived_2 : public Base {
public:
static char v[100];
};
char Derived_2::v[100];
int main() {
Derived_1 c1;
Derived_2 c2;
strcpy(Base::v, "Base");
strcpy(c1.v, "Herbert");
strcpy(c2.v, "Anton");
cout << c1.v << " " << c2.v << endl;
Base* b = &c2;
cout << b->v << endl;
return 0;
}
输出:
Herbert Anton
Base
所以仍然不是你想要实现的;这就是为什么我认为带有类名作为键的地图仍然是一个更好的选择。
答案 1 :(得分:0)
如果你真的需要派生类型的不同数组,我建议使用一个虚拟生成器函数,它返回一个指向静态函数本地数组的指针:
ManyToOne