将 class 成员存储为原始指针的替代方法
Alternatives for storing a class member as a raw pointer
在下面显示的代码示例中 - 在 Container
class 中,它 拥有 (并负责销毁)两个对象 c, d
,它们是摘要 class B
的子classes。 Container
对象可以创建新的 ObjectDisplay
在其构造函数中采用一种 B 。我可以将抽象类型 B 作为指针传递给 ObjectDisplay
并将其存储为 RAW 指针 。但是存储和使用原始指针并始终检查它是否为空指针并不理想。如果 B 不是抽象的 class,我可以将其作为参考传递给 ObjectDisplay
(即 ObjectDisplay (B& b)
)。但由于我无法更改 B,我想知道将 B* 对象作为原始指针存储在 ObjectDisplay
中的替代方案是什么?
// B is abstract
class B
{
public:
virtual int getDefault() = 0;
};
class C : public B
{
public:
int getDefault() override { return 1; }
};
class D : public B
{
public:
int getDefault() override { return 5; }
};
class ObjectDisplay
{
public:
ObjectDisplay (B* b) : object (b) {}
void someFunction()
{
const auto result = b->getDefault();
// do something
}
private:
B* object;
};
class Container
{
public:
void addDisplay()
{
displays.push_back (ObjectDisplay (&c));
displays.push_back (ObjectDisplay (&d));
}
private:
C c;
D d;
std::vector<ObjectDisplay> displays;
};
If B
wasn't an abstract class, I could pass it in ObjectDisplay
as a reference (ie. ObjectDisplay (B& b)
). But since I can't change B
, I wonder what's the aternative of storing B* object
as a raw pointer in ObjectDisplay
?
仅仅因为 B
是一个抽象 class 并不意味着您需要传递它并将其存储为 指针 。您可以传递它并将其存储为 reference。多态性适用于指针和引用。使用参考确实可以解决您的 nullptr
问题,例如:
class ObjectDisplay
{
public:
ObjectDisplay (B& b) : object (b) {}
void someFunction()
{
const auto result = object.getDefault();
// do something
}
private:
B& object;
};
class Container
{
public:
void addDisplay()
{
displays.push_back (ObjectDisplay (c));
displays.push_back (ObjectDisplay (d));
}
private:
C c;
D d;
std::vector<ObjectDisplay> displays;
};
只要 c
和 d
的寿命超过 displays
中的 ObjectDisplay
个对象,无论您使用指针还是引用,都可以。
If B wasn't an abstract class, I could pass it in ObjectDisplay as a reference
不,如果 B
是一个抽象 class,您仍然可以通过引用传递它。 B& object
可以绑定到 B
的子 class 的实例。它的行为几乎与指针相同。
引自cppref:
That is to say, if a derived class is handled using pointer or reference to the base class, a call to an overridden virtual function would invoke the behavior defined in the derived class.
在ObjectDisplay
中声明一个B&
的成员,并通过引用构造它。
class ObjectDisplay
{
public:
ObjectDisplay (B& b) : object (b) {}
private:
B& object;
};
class Container
{
public:
void addDisplay()
{
displays.push_back (ObjectDisplay (c));
displays.push_back (ObjectDisplay (d));
}
};
在线查看demo
旁白:
由于您传递的是直接在 push_back
中构造的临时 ObjectDisplay
对象,我建议您使用 emplace_back
.
void addDisplay()
{
displays.emplace_back (c);
displays.emplace_back (d);
}
在下面显示的代码示例中 - 在 Container
class 中,它 拥有 (并负责销毁)两个对象 c, d
,它们是摘要 class B
的子classes。 Container
对象可以创建新的 ObjectDisplay
在其构造函数中采用一种 B 。我可以将抽象类型 B 作为指针传递给 ObjectDisplay
并将其存储为 RAW 指针 。但是存储和使用原始指针并始终检查它是否为空指针并不理想。如果 B 不是抽象的 class,我可以将其作为参考传递给 ObjectDisplay
(即 ObjectDisplay (B& b)
)。但由于我无法更改 B,我想知道将 B* 对象作为原始指针存储在 ObjectDisplay
中的替代方案是什么?
// B is abstract
class B
{
public:
virtual int getDefault() = 0;
};
class C : public B
{
public:
int getDefault() override { return 1; }
};
class D : public B
{
public:
int getDefault() override { return 5; }
};
class ObjectDisplay
{
public:
ObjectDisplay (B* b) : object (b) {}
void someFunction()
{
const auto result = b->getDefault();
// do something
}
private:
B* object;
};
class Container
{
public:
void addDisplay()
{
displays.push_back (ObjectDisplay (&c));
displays.push_back (ObjectDisplay (&d));
}
private:
C c;
D d;
std::vector<ObjectDisplay> displays;
};
If
B
wasn't an abstract class, I could pass it inObjectDisplay
as a reference (ie.ObjectDisplay (B& b)
). But since I can't changeB
, I wonder what's the aternative of storingB* object
as a raw pointer inObjectDisplay
?
仅仅因为 B
是一个抽象 class 并不意味着您需要传递它并将其存储为 指针 。您可以传递它并将其存储为 reference。多态性适用于指针和引用。使用参考确实可以解决您的 nullptr
问题,例如:
class ObjectDisplay
{
public:
ObjectDisplay (B& b) : object (b) {}
void someFunction()
{
const auto result = object.getDefault();
// do something
}
private:
B& object;
};
class Container
{
public:
void addDisplay()
{
displays.push_back (ObjectDisplay (c));
displays.push_back (ObjectDisplay (d));
}
private:
C c;
D d;
std::vector<ObjectDisplay> displays;
};
只要 c
和 d
的寿命超过 displays
中的 ObjectDisplay
个对象,无论您使用指针还是引用,都可以。
If B wasn't an abstract class, I could pass it in ObjectDisplay as a reference
不,如果 B
是一个抽象 class,您仍然可以通过引用传递它。 B& object
可以绑定到 B
的子 class 的实例。它的行为几乎与指针相同。
引自cppref:
That is to say, if a derived class is handled using pointer or reference to the base class, a call to an overridden virtual function would invoke the behavior defined in the derived class.
在ObjectDisplay
中声明一个B&
的成员,并通过引用构造它。
class ObjectDisplay
{
public:
ObjectDisplay (B& b) : object (b) {}
private:
B& object;
};
class Container
{
public:
void addDisplay()
{
displays.push_back (ObjectDisplay (c));
displays.push_back (ObjectDisplay (d));
}
};
在线查看demo
旁白:
由于您传递的是直接在 push_back
中构造的临时 ObjectDisplay
对象,我建议您使用 emplace_back
.
void addDisplay()
{
displays.emplace_back (c);
displays.emplace_back (d);
}