gpt4 book ai didi

C++ - 如何在同一类的实例之间更新指针(或成员)

转载 作者:行者123 更新时间:2023-11-30 05:40:45 24 4
gpt4 key购买 nike


我有一个简单的类,它由一个 void 指针和一个 int 组成(这是某种 boost::Variant 教育项目)。
我还有一个工作拷贝构造函数和一个析构函数。

但让我苦恼的是,我将如何完成这样的事情:

Container cont1("some value"); //simple construction
Container cont2;
cont2.createLink(cont1); //this should initialize members with a reference (or something alike)
std::cout<<cont1; //yields "some value"

cont2.set(20); //setting this container should update the original container too, since I initialized with a reference (or smth alike)
std::cout<<cont1; //yields 20

这是类的简化版本:

class Container {
public:
Container(){}
Container(const std::string &val){var.type = STRING; var.data = new std::string(val);}
Container(int val){ /* same for int */}
Container(const Container &val){ /* do a memory copy */}

void set(int val){ /* set the value if type matches, otherwise allocate a new pointer */}
void set(const std::string &val){ /* the same as for int */}
void createLink(const Container &val){ /* somehow assign a reference or whatsoever */}
private:
typedef struct VAR {
int type = 0;
void *data = NULL; }
VAR var;
}

如果我将 cont2 的值设置为 string(即它目前持有的相同数据类型),一切都很好,因为该集合不会分配一个新指针,而是分配一个新值。
但是,如果我为 cont2 分配不同的值并因此必须分配一个新指针,我如何确保 cont1 的指针更新?

我需要像 shared_pointer 这样的东西吗?

感谢您的任何见解!

编辑:

我更改为函数名称是为了更清楚应该发生什么。

最佳答案

有一个只涉及直接 OO 的解决方案。您可以为您的变体类型创建一个接口(interface),并对变体实例使用双重间接以允许链接的容器共享相同的变体实例。

之所以需要双重间接寻址,是因为您希望 set() 方法在新类型与原始类型不匹配时自动分配新的变体实例。如果我们简单地从两个容器共享一个指向变体的指针,那么在 set() 创建一个新的变体实例之后,每个容器将再次引用不同的实例。

为了解决这个问题,我们可以使用指向容器中变体的指针。

这里有一个可能的方法来定义你的变体接口(interface),以及它如何被子类化:

typedef std::ostream Out;
struct BadType {};

struct Var {
virtual ~Var () = default;
virtual Out & print (Out &os) { return os << "(BadType)"; }
virtual void set (int) { throw BadType(); }
virtual void set (const std::string &) { throw BadType(); }
};

struct VarInteger : Var {
int data;
VarInteger (int v) : data(v) {}
Out & print (Out &os) { return os << data; }
void set (int v) throw() { data = v; }
};

struct VarString : Var {
std::string data;
VarString (const std::string &v) : data(v) {}
Out & print (Out &os) { return os << data; }
void set (const std::string &v) throw() { data = v; }
};

这里是你如何定义你的指针到指针,以及如何初始化它们:

typedef std::shared_ptr<Var> VarPtr;
std::shared_ptr<VarPtr> varptr_;

static VarPtr make_var () { return std::make_shared<Var>(); }
static VarPtr make_var (int v) { return std::make_shared<VarInteger>(v); }
static VarPtr make_var (const std::string &v) {
return std::make_shared<VarString>(v);
}

VarPtr & var () { return *varptr_; }
const VarPtr & var () const { return *varptr_; }

Container () : varptr_(std::make_shared<VarPtr>(make_var())) {}
Container (int v) : varptr_(std::make_shared<VarPtr>(make_var(v))) {}
Container (const std::string &v)
: varptr_(std::make_shared<VarPtr>(make_var(v))) {}

下面是您的 set() 方法和 createLink() 方法的实现方式。

void set (int v) {
try { var()->set(v); }
catch (BadType) { var() = make_var(v); }
}

void set (const std::string &v) {
try { var()->set(v); }
catch (BadType) { var() = make_var(v); }
}

void createLink (const Container &val) { varptr_ = val.varptr_; }

Demo

关于C++ - 如何在同一类的实例之间更新指针(或成员),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31479260/

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