gpt4 book ai didi

c++ - 对多态对象成员的无效引用

转载 作者:行者123 更新时间:2023-11-30 05:34:08 25 4
gpt4 key购买 nike

假设我有两个类 FooBar继承接口(interface)Base并希望将这些类的实例存储在 std::vector<std::unique_ptr<Base>> 类型的 vector 中. Bar 的对象type 应该存储对值的引用(在这种情况下,它是 Foo 类的成员)。从概念上讲,我想实现以下目标:

#include <iostream>
#include <memory>
#include <vector>

template<typename Type, typename ... Types>
std::unique_ptr<Type> make_unique(Types &&... arguments) {
return std::unique_ptr<Type>(new Type(std::forward<Types>(arguments)...));
}

class Base {
public:
virtual ~Base() = 0;
virtual void execute() = 0;
};

Base::~Base() {
}

class Foo: public Base {
public:
void execute() override {
// Foo-specific implementation of execute(), may change value_
value_ = 2;
}
const int & value() const {
return value_;
}
private:
int value_;
};

class Bar: public Base {
public:
Bar(const int &value) : value_(value) {}
void execute() override {
// Bar-specific implementation of execute(), uses current value_
std::cout << value_ << std::endl;
}
private:
const int &value_; // Reference to a value, not necessarily from Foo
};

int main() {
// Collection of base objects, possibly inside another object
std::vector<std::unique_ptr<Base>> baseVector;
baseVector.emplace_back(make_unique<Foo>());
baseVector.emplace_back(make_unique<Bar>(
dynamic_cast<Foo *>(baseVector.back().get())->value()));
for (auto &base : baseVector)
base->execute();

return 0;
}

然而,dynamic_cast我觉得很臭(我知道我也可以使用 static_cast,但我想那也好不了多少)。避免 dynamic_cast 的替代方法将是更改 Foo类看起来像

class Foo: public Base {
public:
Foo() : value_(new int()) {}
void execute() override {
// Foo-specific implementation of execute(), may change value_
*value_ = 2;
}
const int & value() const {
return *value_;
}
private:
std::unique_ptr<int> value_;
};

然后做

int main() {
// Collection of base objects, possibly inside another object
std::vector<std::unique_ptr<Base>> baseVector;
auto foo = make_unique<Foo>();
auto *fooPtr = foo.get();
baseVector.emplace_back(std::move(foo));
baseVector.emplace_back(make_unique<Bar>(fooPtr->value()));
for (auto &base : baseVector)
base->execute();

return 0;
}

但这也似乎不是很优雅。如何妥善处理这些情况?

最佳答案

我会以更通俗易懂的方式编写它:

struct Base { virtual ~Base() = default; /* ...*/ };
struct Foo : Base { int x_; int & value() { return x_; /* ...*/ };
struct Bar : Base { int & r_; Bar(int & r) : r_(r) {} /* ...*/ };

auto foo = std::make_unique<Foo>();
auto bar = std::make_unique<Bar>(foo->value());

v.push_back(std::move(foo));
v.push_back(std::move(bar));

仅仅因为 emplace_back 存在并不意味着您必须将它用于所有事情!

关于c++ - 对多态对象成员的无效引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34382748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com