访问子类的属性/函数
Accessing Properties/Functions of Subclasses C++
我在我的程序中有一个设计问题,因为我需要偶尔访问属性&所有子类的方法都存储在基类指针的向量中。我的代码看起来像这样:
class B1;
class B2;
class Base {
private:
int id, a, b;
public:
virtual int getA() { return a; }
virtual int getB() { return b; }
virtual B1 *getB1() { return NULL; } //seems like a bad idea
virtual B2 *getB2() { return NULL; } //to have these two functions
Base(int newId) { id = newId; }
};
class B1 : public Base {
private:
int x;
public:
int getX() { return x; }
B1 *getB1() { return this; }
};
class B2 : public Base {
private:
int y;
public:
int getY() { return y; }
B2 *getB2() { return this; }
};
class Thing {
private:
std::vector<Base*> bases;
void addBase(Base *base) { bases.push_back(base); }
void doB1Stuff();
void doB2Stuff();
void setAandB(int ID, int newA, int newB); //set a and b of one of the elements in bases vector based upon the id given
};
问题是,如果我需要在Thing中访问x或y,如下所示:
void Thing::doB1Stuff() {
for(std::vector<Base*>::iterator it = bases.begin(); it != bases.end(); ++it) {
if (it->getB1()) {
//do stuff with b1
}
}
}
上面的代码应该可以工作,但这似乎是一个坏主意,因为在使用B1/B2属性之前很容易忘记检查指针是否为空,像这样:
void Thing::doB2Stuff() {
for(std::vector<Base*>::iterator it = bases.begin(); it != bases.end(); ++it) {
std::cout << it->getY(); //I believe this will crash the program if a NULL pointer is returned
}
}
我的问题是:访问子类属性的好方法是什么?我想在Thing中有两个单独的向量B1s和B2s,但这似乎也不是一个好主意因为我需要能够轻松地设置a和b。任何想法吗?
你所拥有的是非常好的:只要你不将NULL
s存储在指针的bases
向量中,就不需要对迭代器返回的值进行空检查。不幸的是,指针向量是多态对象容器的唯一选择。您可以创建共享指针的向量来简化删除处理,但基本思想将保持不变。
您可以检查您正在访问的项目是否是您正在寻找的正确子类类型,尽管要做到这一点,您需要包含运行时类型信息(rtti)。
然后,如果它是某种类型且不为空,则可以将其强制转换为该类型并调用正确的函数。
你也可以使用dynamic_cast,虽然要使它工作,你需要再次使用rtti,它本质上是相同的检查自己,然后静态转换
你是对的,这不是一个解决问题的好方法,你可以使用dynamic_cast
来有一个安全的方法来确定使用哪个对象,但这对我来说是糟糕的代码气味。
要访问子属性,我要做的是创建一个虚函数,该虚函数返回您在基类中想要的值。
的例子:
class Base {
private:
int id, a, b;
public:
virtual int getA() { return a; }
virtual int getB() { return b; }
virtual int getSubValue() = 0; //
Base(int newId) { id = newId; }
};
class B1 : public Base {
private:
int x;
public:
int getSubValue() { return x; }
};
class B2 : public Base {
private:
int y;
public:
int getSubValue() { return y; }
};
然后你可以调用它->getSubValue()来获取你请求的子值。
这是我的观点,有很多方法可以处理这个问题,但这是我根据您提供的信息提出的建议。
相关文章:
- 主函数参数的属性
- C++调用具有 *this 属性的单个帮助程序函数
- 使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?
- c++ 构造函数 将 1 个字符串参数转换为 3 个属性
- 如何在不知道属性具有哪些构造函数的情况下初始化属性?
- C++ 类/结构中的函数依赖属性
- C++ 中常量属性的初始化构造函数错误
- 在构造函数 c++ 中初始化属性时出现问题
- 静态类属性,C++中的多个构造函数
- 使用智能指针属性创建资源库函数?
- 模板化虚拟函数,管理单个类的不同类属性
- 使用类属性调用具有非类型模板参数的模板函数
- 设置使用 Cereal 序列化库时可以在序列化函数中访问的属性
- pybind11:属性错误:尝试从 py 文件运行函数时,模块'XXX'没有属性'YYY'
- 用于指示返回值生存期的C++函数属性和参数相同
- 为什么'mutable' lambda 函数属性,而不是捕获类型?
- -fno将严格别名作为函数属性
- gcc函数属性-如何使用它们
- 函数属性returns_twice
- Visual Studio 2015 Update 3 是否中断了构造函数属性