gpt4 book ai didi

c++ - 意外的引用行为

转载 作者:行者123 更新时间:2023-12-04 14:05:36 26 4
gpt4 key购买 nike

我正在研究复合模式并遇到以下代码的意外行为:

namespace Composit
{

class Component
{
public:
virtual ~Component() { }
virtual void operation() = 0;
protected:
private:
};

class Leaf : public Component
{
public:
Leaf() { }
virtual ~Leaf() { }
void operation() override
{
// Implementation of operation for a leaf
std::cout << this << ": I am a leaf" << std::endl;
}

protected:

private:
};

class Composit : public Component
{
public:

Composit(Component& x) :
child_(x)
{ }

virtual ~Composit() { }

void operation() override
{
// Implementation of operation for a composit
std::cout << this << ": I am a composit! " << std::endl;
child_.operation();
}

protected:
Component& child_;

private:
};
}

int main()
{
Composit::Leaf a;
Composit::Composit b(a); // b->a
Composit::Composit c(b); // c->b->a
Composit::Composit d(c); // d->c->b->a
}

如评论中所示,我希望有某种形式的递归链接。相反,我发现“b”、“c”和“d”的“child_”引用了“a”。当 Composit 构造函数的参数是指向组件的指针时,我可以获得预期的行为。

Composit(Component* x) :
child_(*x)
{ }

而变量b,c,d的定义显然是使用了a,b,c的地址

Composit::Leaf a;
Composit::Composit b(&a); // b->a
Composit::Composit c(&b); // c->b->a
Composit::Composit d(&c); // d->c->b->a

使用引用作为参数的版本是否没有像我预期的那样工作?

谢谢。

编辑:我试过这段代码

void f(Composit::Component& x)
{
x.operation();
}



int main()
{
Composit::Leaf a;
Composit::Composit b(a); // b->a
Composit::Composit c(b); // c->b->a
Composit::Composit d(c); // d->c->b->a

f(d);
f(c);
f(b);
f(a);

}

得到这个输出

00D7F858: I am a composit!
00D7F888: I am a leaf
00D7F868: I am a composit!
00D7F888: I am a leaf
00D7F878: I am a composit!
00D7F888: I am a leaf
00D7F888: I am a leaf

这是我传递指针时得到的结果

int main()
{
Composit::Leaf a;
Composit::Composit b(&a); // b->a
Composit::Composit c(&b); // c->b->a
Composit::Composit d(&c); // d->c->b->a

f(d);
f(c);
f(b);
f(a);

}
00DEF9D4: I am a composit!
00DEF9E4: I am a composit!
00DEF9F4: I am a composit!
00DEFA04: I am a leaf
00DEF9E4: I am a composit!
00DEF9F4: I am a composit!
00DEFA04: I am a leaf
00DEF9F4: I am a composit!
00DEFA04: I am a leaf
00DEFA04: I am a leaf

最佳答案

因为Composit::Composit c(b)调用了拷贝构造函数,默认生成。这就是指针版本起作用的原因,因为 Composit* 参数不适用于复制构造函数。

没有很好的方法来防止这种行为,因为如果 Composit::Composit c(b) 是有效的,大多数容器/通用算法会期望这是一个拷贝(但它不会是,因为它只会使 c 成为 b 的包装器)。我会建议使用工厂函数来制作 Composit 对象。

关于c++ - 意外的引用行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68632984/

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