我正在努力用C ++调用虚函数。
我没有C ++经验,我主要使用C#和Java,所以我可能会有一些妄想,但请耐心等待。
我必须编写一个程序,如果可能的话我必须避免动态内存分配。我创建了一个名为List的类:
template <class T> class List {
public:
T items[maxListLength];
int length;
List() {
length = 0;
}
T get(int i) const {
if (i >= 0 && i < length) {
return items[i];
} else {
throw "Out of range!";
}
};
// set the value of an already existing element
void set(int i, T p) {
if (i >= 0 && i < length) {
items[i] = p;
} else {
throw "Out of range!";
}
}
// returns the index of the element
int add(T p) {
if (length >= maxListLength) {
throw "Too many points!";
}
items[length] = p;
return length++;
}
// removes and returns the last element;
T pop() {
if (length > 0) {
return items[--length];
} else {
throw "There is no element to remove!";
}
}
};
它只是生成给定类型的数组,并管理它的长度。
不需要动态内存分配,我可以写:
List<Object> objects;
MyObject obj;
objects.add(obj);
MyObject继承表单Object。 Object有一个虚函数,应该在MyObject中重写:
struct Object {
virtual float method(const Input& input) {
return 0.0f;
}
};
struct MyObject: public Object {
virtual float method(const Input& input) {
return 1.0f;
}
};
我得到的元素为:
objects.get(0).method(asdf);
问题是即使第一个元素是MyObject,也会调用Object的方法函数。我猜测将对象存储在一个Object数组中而没有为MyObject动态分配内存有什么问题,但我不确定。
有没有办法调用MyObject的方法函数?怎么样?它应该是一个异构的集合btw,所以这就是为什么继承就在那里。
如果无法调用MyObject的方法函数,那么我该如何制作我的列表呢?
此外,我无法访问math.h和stdlib.h之外的库,因此例如,vector不可用。
答案 0 :(得分:4)
您需要在列表中存储指针。试试这个:
List<Object*> objects;
Object *obj1 = new Object;
MyObject *obj2 = new MyObject;
Object *obj3 = new MyObject;
objects.add(obj1);
objects.add(obj2);
objects.add(obj3);
// This calls the implementation in Object class
objects.get(0)->method(asdf);
// This calls the implementation in MyObject class
objects.get(1)->method(asdf);
// This calls the implementation in MyObject class
// Polymorphism here
objects.get(2)->method(asdf);
希望这有帮助。
答案 1 :(得分:1)
执行此操作时:
objects.add(obj);
您正在将MyObject的Object部分的副本添加到列表中,因此它不再是MyObject。
你可能想尝试这样做:
int add(T const &p) {
if (length >= maxListLength) {
throw "Too many points!";
}
items[length] = p; // now the problem is here
return length++;
}
但现在p的Object部分的副本在分配期间发生。
要使列表成为异构列表,它必须是一个指针列表,但您还希望避免动态内存分配。如果您小心,可以避免动态内存分配:
Object obj1;
MyObject obj2;
List<Object*> object_ptrs;
object_ptrs.add(&obj1);
object_ptrs.add(&obj2);
object_ptr.get(1)->method(input);
object_ptr.get(0)->method(input);
但是,你必须非常小心。该列表现在指向堆栈上的两个对象。如果从此函数返回,那么这两个对象将被销毁。请注意,我故意将对象指针列表放在对象之后,这样列表就会在对象之前被销毁,因此列表不会指向垃圾。但是,如果您返回列表的副本,则仍会出现问题。