繁体   English   中英

访问接口向量中对象的字符串视图 C++

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM