我正在开展一个项目,而且我处于一个我不知道什么是错的阶段。这是简化版本:
代码:
class Base { // This base class is pure abstract
public:
virtual ~Base(); // Necessary to trigger destructors in inherited classes
virtual baseFunc() = 0;
};
class DerivedA : public Base{
public:
DerivedA(SomeClassUseBase * tmp){
tmp -> register(this);
}
~DerivedA();
void baseFunc(){
// do something here that's only for DerivedA
}
};
class DerivedB : public Base{
public:
DerivedB(SomeClassUseBase * tmp) {
tmp -> register(this);
}
~DeriveB();
void baseFunc(){
// do something here that's only for DerivedB
}
};
class SomeClassUseBase {
private:
Base ** basePrt;
unsigned int index;
public:
someClassUseBase(int num) {
basePrt = new Base*[num]; //create an array of pointers to the objects
index = 0;
}
void register( Base * base ){
//i tried *(basePrt[index]) = *base, but got the same problem
basePrt[index] = base;
index = index + 1;
}
void checkList() {
for (int i = 0; i < index ;i++){
next = basePrt[i];
next -> baseFunc(); //fails here
}
}
};
int main() {
SomeClassUseBase tmp = new SomeClassUseBase(5);
Base *b[5];
for ( i = 0; i < 5; i += 1 ) {
if ( i % 2 == 0 ) {
b[i] = new DerivedA(&tmp);
}
else {
b[i] = new DerivedB(&tmp);
// the object pointed by tmp::basePrt[0] is lost after this line
} // if
} // for
tmp.checkList(); //crashes here since tmp.bastPrt[0] points to null
}
问题在于,当在main中,我在创建第一个DerivedB时到达该行,tmp.basePrt [0]已经创建的DerivedA指针会丢失一些。我不知道为什么,但我怀疑这与多态性有关?请帮忙!!谢谢!
编辑:
第一次没有完全正确的代码,对不起......
答案 0 :(得分:4)
您正在Array Base * b [5]中创建5个对象(DerivedA / B),但是在您的checkList()中,您无权访问这些对象。尝试以某种方式将此数组放入tmp或实例化tmp中的DerivedA / B对象。
在当前形式中,tmp内和main()内的两个数组都没有连接,这就是为什么在运行main()之后你在tmp中仍然有一个空数组。
<强>更新强>
另请注意,index
(无符号整数)成员的类型与循环变量i
的类型(当前为整数)匹配。
接下来的尝试是明确地在DerivedA / B中使你的方法virtual
(也是析构函数!)。根据编译器的不同,这可能会导致您对baseFunc()的调用仍然解析为Base的'null'主体。
最后,如果它真的是C ++,你可以尝试使用引用,所以你的构造函数看起来像
DerivedA(SomeClassUseBase& tmp) {
tmp.register(this);
}
请注意点运算符的使用而不是' - &gt;',它使事情更容易阅读和维护。
答案 1 :(得分:3)
for循环的结束括号在哪里?
void checkList() {
for (int i = 0; i < index ;i++){
next = basePrt[i];
next -> baseFunc(); //fails here
} // this one is missing in the example !
}
使用矢量...
class SomeClassUseBase {
private:
std::vector<Base*> basePrt;
public:
void register( Base * base ){
basePrt.push_back(base);
}
void checkList() {
std::for_each( basePrt.begin(), basePrt.end(), std::mem_fun(&Base::baseFunc);
}
};
这对我有用。这不是我为我的项目编写的代码,但它有效。
class SomeClassUseBase;
class Base { // This base class is pure abstract
public:
virtual ~Base() {} // Necessary to trigger destructors in inherited classes
virtual void baseFunc() = 0;
};
class DerivedA : public Base {
public:
DerivedA(SomeClassUseBase * tmp){
tmp -> registerIt(this);
}
void baseFunc(){
// do something here that's only for DerivedA
}
};
class DerivedB : public Base {
public:
DerivedB(SomeClassUseBase * tmp){
tmp -> registerIt(this);
}
void baseFunc() {
// do something here that's only for DerivedB
}
};
class SomeClassUseBase {
private:
Base ** basePrt; //Remark: use a vector or shared_array
unsigned int index;
SomeClassUseBase(const SomeClassUseBase&);
const SomeClassUseBase& operator=(const SomeClassUseBase&);
public:
explicit SomeClassUseBase(int num) {
//Remark: Store the size of the container
basePrt = new Base*[num]; //create an array of pointers to the objects
index = 0;
}
~SomeClassUseBase() {
delete[] basePrt;
}
void registerIt( Base * base ) {
//Remark: what if index >= size of the array?
basePrt[index] = base;
index = index + 1;
}
void checkList() const {
for (int i = 0; i < index ;i++){
Base *next = basePrt[i];
next->baseFunc();
}
}
};
int main() {
SomeClassUseBase tmp(5);
Base *b[5]; //Remark: Use a smart_pointer
for ( int i = 0; i < 5; i += 1 ) {
if ( i % 2 == 0 ) {
b[i] = new DerivedA(&tmp);
}
else {
b[i] = new DerivedB(&tmp);
} // if
} // for
tmp.checkList();
for(int i = 0; i < 5; ++i ) {
delete b[i];
}
}