我创建的类是指向基类的指针的容器。我可以添加基类对象以及派生类对象。但是,当我尝试使用派生类对象中的函数时,我得到了编译错误“'Base'类没有名为'name'的成员”。 代码看起来像这样:
#include <cstdio>
#include <vector>
using namespace std;
enum Type{
obj,
obj1,
obj2
};
class Base{
public:
void fun(){
printf("I'm base\n");
}
};
class Derived1 : public Base{
public:
void fun2(){
printf("I'm derived1\n");
}
};
class Derived2 : public Base{
public:
void fun3(){
printf("I'm derived2\n");
}
};
class myVector{
private:
vector<Base*> objects;
public:
void add(Type type){
switch(type){
case obj:
objects.push_back(new Base);
break;
case obj1:
objects.push_back(new Derived1);
break;
case obj2:
objects.push_back(new Derived2);
break;
}
}
Base* operator[](unsigned index){
return objects[index];
}
};
int main(){
myVector vec;
vec.add(obj);
vec.add(obj1);
vec.add(obj2);
vec[0]->fun(); // ok
vec[1]->fun1(); // error "Base" has not member named "fun1"
vec[2]->fun2(); // error "Base" has not member named "fun2"
}
应打印
我是基地 我是派生的1 我是派生的2
但是我的编辑错误就像在评论中的代码一样
答案 0 :(得分:1)
你应该把它变成虚函数并在派生类中重写它
#include <cstdio>
#include <vector>
using namespace std;
enum Type{
obj,
obj1,
obj2
};
class Base{
public:
virtual void fun(){
printf("I'm base\n");
}
};
class Derived1 : public Base{
public:
void fun(){
printf("I'm derived1\n");
}
};
class Derived2 : public Base{
public:
void fun(){
printf("I'm derived2\n");
}
};
class myVector{
private:
vector<Base*> objects;
public:
void add(Type type){
switch(type){
case obj:
objects.push_back(new Base);
break;
case obj1:
objects.push_back(new Derived1);
break;
case obj2:
objects.push_back(new Derived2);
break;
}
}
Base* operator[](unsigned index){
return objects[index];
}
};
int main(){
myVector vec;
vec.add(obj);
vec.add(obj1);
vec.add(obj2);
vec[0]->fun(); // ok
vec[1]->fun(); // now it works
vec[2]->fun(); // now it works
}
答案 1 :(得分:0)
C ++在编译时静态解析名称。你告诉它你有Base*
。这些是您通过该指针允许在该对象上使用的名称。想要访问Derived
中您必须投射的内容。
答案 2 :(得分:0)
如果您希望能够通过基类指针调用方法,则需要在基类中定义这些方法(可能是纯虚方法)。
如果您知道自己有子类对象,则可能需要static_cast
(或者可能dynamic_cast
并测试),并通过强制转换指针调用该方法。
如果不了解fun1()
和fun2()
的语义,就无法知道哪种替代方案最适合您的情况。
这是一个做你想要的版本 - 请注意Base::fun
被声明为virtual
,子类实现会覆盖它。
#include <iostream>
#include <vector>
struct Base {
virtual void fun() const {
std::cout << "I'm base" << std::endl;
}
virtual ~Base() = default;
};
struct Derived1 : public Base{
void fun() const override {
std::cout << "I'm derived1" << std::endl;
}
};
struct Derived2 : public Base{
void fun() const override {
std::cout << "I'm derived2" << std::endl;
}
};
int main(){
std::vector<Base*> vec{new Base(), new Derived1(), new Derived2()};
vec[0]->fun();
vec[1]->fun();
vec[2]->fun();
// cleanup
for (auto e: vec)
delete e;
}