gpt4 book ai didi

c++ - 通过扩展添加可变性

转载 作者:太空狗 更新时间:2023-10-29 20:56:25 24 4
gpt4 key购买 nike

我有一个Data 类和一个Wrapper 类,它提供了访问Data 的方法。 WrapperMutable 类扩展了 Wrapper 以添加修改 Data 的方法。

#include <memory>
using namespace std;

class Data {
public:
void update(); // non-const method which modifies internal state of Data
};

class Wrapper
{
public:
Wrapper(shared_ptr<Data const> data) : myData(data) {} // accepts const pointer
// ...bunch of functions providing read-only access to aspects of the Data...
protected:
shared_ptr<Data const> myData; // stores const pointer
};

// Extend Wrapper with methods to modify the wrapped Data.
class WrapperMutable : public Wrapper
{
public:
WrapperMutable(shared_ptr<Data> data) : Wrapper(data) {}

// ERROR: invoking non-const method on const object:
void updateData() { myData->update(); }
};

问题当然出在被包装的Data 对象的const 特性上,这意味着WrapperMutable 不能修改它。

我考虑过更改 Wrapper 以接受和存储非 const Data,但客户端本身通常只能访问 const Data,因此他们将被迫 const_cast 或复制以创建 Wrapper

所以我能够实现这一点的唯一方法是在 WrapperMutable 类中保留一个额外的非 const 指针,并在可变上下文中使用它:

class WrapperMutable : public Wrapper
{
public:
WrapperMutable(shared_ptr<Data> data) : Wrapper(data), myMutableData(data) {}

// Use myMutableData instead of the const myData
void updateData() { myMutableData->update(); }

private:
shared_ptr<Data> myMutableData; // non-const pointer to the same Data as in Wrapper
};

有没有更好的方法?显然,从 Wrapper 派生 WrapperMutable 是我问题的根源,但我不想在中重新实现 Wrapper 的所有方法WrapperMutable 要么。

最佳答案

继承表示一种“种类”关系。

常量不是一种“种类”关系。

常量事物与可变事物截然不同。

shared_ptr 的模型本身就展示了如何表达这种关系。可变数据的 shared_ptr 可转换为常量数据的 shared_ptr,但反之则不行。

你可以这样表达这种关系:

#include <iostream>
#include <memory>

struct Data
{
};

struct const_data_wrapper
{
const_data_wrapper(std::shared_ptr<const Data> p) : _impl(std::move(p)) {}

void which() const {
std::cout << "const" << std::endl;
}

private:
std::shared_ptr<const Data> _impl;
};

struct data_wrapper
{
data_wrapper(std::shared_ptr<Data> p) : _impl(std::move(p)) {}

const_data_wrapper as_const() const {
return const_data_wrapper(_impl);
}

void which() const {
std::cout << "not const" << std::endl;
}

private:
std::shared_ptr<Data> _impl;
};

using namespace std;

auto main() -> int
{
auto w1 = data_wrapper(make_shared<Data>());
auto w2 = w1.as_const();

w1.which();
w2.which();

return 0;
}

输出:

not const
const

关于c++ - 通过扩展添加可变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33629801/

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