[英]Access a string view of an object inside a vector of interfaces C++
我将从单个向量中的同一接口继承的不同对象存储起来。 这些对象将它们的名称存储为常量字符串视图,甚至在对象被实例化之前就获取了它的值。 在它存储在向量中之前,我能够轻松地检索它的名称。 但是,当我将它存储在一个接口向量中并再次访问它的名称时,我得到了未定义的行为(依赖于编译器)。 我怎样才能解决这个问题?
这是证明我的问题的最简单的案例。 我正在使用支持 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*>
时,代码运行没有任何问题。 但是,这不是解决方案,因为我想在单个向量中存储从同一接口继承的多种类型。
数据成员不能被覆盖。 基类和派生类中的每个name
都是一个不同的成员,您将在表达式中命名的成员取决于表达式中对象的静态类型,如果您遍历向量,则为IFoo
,而当您引用时,则为Foo
foo
声明为Foo*
。
只有virtual
成员函数具有多态行为。 所以你需要改用一个:
struct IFoo {
public:
virtual ~IFoo() = default;
virtual std::string_view name() const = 0;
};
struct Foo : public IFoo {
public:
std::string_view name() const override {
return "bar";
}
};
//...
for (auto foo : foos) {
std::cout << "Name of object after storing: " << foo->name() << std::endl;
}
为了内存和异常安全,使用std::unique_ptr<IFoo>
和std::make_unique<Foo>
而不是IFoo*
和new Foo
也是一个好主意。 (然后auto foo
将需要改为auto& foo
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.