我将从同一接口继承的不同对象存储在一个向量中。这些对象的名称存储为常量字符串视图,该视图甚至在对象示例化之前就获得其值。我能够在将其存储在向量中之前轻松检索其名称。然而,当我将其存储在接口向量中并再次访问其名称时,我得到了未定义的行为(依赖于编译器)。我该如何解决这个问题?
这里有一个最简单的例子来说明我的问题。我使用的编译器支持C++17和C ++20的一些特性
#include <string_view>
#include <vector>
#include <iostream>
struct IFoo {
public:
virtual ~IFoo() = default;
const std::string_view name{};
};
struct Foo : public IFoo {
public:
const std::string_view name = "bar";
};
int main() {
std::vector<IFoo*> foos;
Foo *foo = new Foo();
std::cout << "Name of object before storing: " << foo->name << std::endl;
foos.push_back(new Foo());
for (auto foo : foos) {
std::cout << "Name of object after storing: " << foo->name << std::endl;
}
}
它产生以下结果:
Name of object before storing: bar
Name of object after storing:
当我尝试将向量更改为std::vector<Foo*>
时,代码运行没有任何问题,但是,这不是一个解决方案,因为我想将从同一接口继承的多个类型存储在一个向量中。
1条答案
按热度按时间enyaitl31#
数据成员不能被重写。基类和派生类中的每个
name
都是不同的成员,在表达式中命名哪个成员取决于表达式中对象的静态类型,如果迭代向量,则为IFoo
,但如果引用声明为Foo*
的foo
,则为Foo
。只有
virtual
成员函数有多态行为,所以你需要使用一个:为了内存和异常安全,使用
std::unique_ptr<IFoo>
和std::make_unique<Foo>
而不是IFoo*
和new Foo
也是一个好主意(那么auto foo
就需要改为auto& foo
)。