我有一个类似于
的抽象类class Protocol
{
public:
// format the string to json or xml depending on impl
virtual std::string& format(Message& msg) = 0;
// parse the message from json or xml depending on impl
virtual Message& parse(std::string& str) = 0;
}
用于格式化从structure Message
std::string
struct Message
{
unsigned long id;
unsigned char command;
unsigned int value;
/* some more fields */
}
现在我有另一个类``通过拥有该类型的成员来依赖该类。当然,该成员应具有Calculator
// client.h
class Client
{
public:
Client(Protocol& protocol);
/* some methods, e.g. */
void request(unsigned int amout);
private:
/* this is what the question below refers to */
Protocol* pProtocol; // will compile
Protocol cProtocol; // won't compile (see below)
Protocol& rProtocol; // what does this mean?
}
// client.cpp
Client::Client(Protocol& protocol) :
// depending on the member
pProtocol(&protocol) // or
cProtocol(protocol) // or
rProtocol(protocol)
{
}
void Client::request(unsigned int amount)
{
Message msg;
msg.id = 1234;
msg.command = 100;
msg.value = amount;
std::string str =
// depending on the member
pProtocol->format(msg); // or
cProtocol.format(msg); // or
rProtocol.format(msg);
// some more code to send the string to the server
}
所以这是我的问题:
我知道我应该更喜欢像cProtocol
这样的类类型的成员,因为pProtocol
之类的指针可能是NULL
遗憾的是,这不会使用消息
进行编译cannot declare field 'Client::cProtocol' to be of abstract type 'Protocol'
我理解,因为抽象类Protocol
无法实例化。
所以我应该更喜欢什么?引用成员或指针成员?
3个选项之间有什么区别?特别是在cProtocol
和rProtocol
之间(.
vs。->
除外指针可能是NULL
)
如果我没有在构造函数中初始化rProtocol
怎么办?这会编译吗?它包含什么?由于无法使用默认值进行实例化!?
答案 0 :(得分:2)
我知道我应该更喜欢像
cProtocol
这样的类类型的成员,因为pProtocol
之类的指针可能是NULL
通常,您更喜欢对象到指针,因为该语言可以通过调用它们上的析构函数来帮助您管理资源。但是,您可以使用智能指针实现相同的效果,例如std::shared_ptr<T>
或std::unique_ptr<T>
。
遗憾的是,由于抽象类协议无法实例化,因此无法使用“无法声明字段
Client::cProtocol
为抽象类型Protocol
”的消息进行编译,因为无法实例化抽象类协议。
这不是正确的理由:它是因为object slicing而完成的,因为不允许将对象切割为抽象类型。
那我应该更喜欢什么?引用成员或指针成员?
为了使用参考,需要三个条件:
NULL
的引用)和如果满足这三个条件,您可以使用参考。这告诉读者您的类实例与引用的实例有很强的界限,因为上面有三个条件。
3个选项有什么区别?特别是在
cProtocoland
rProtocol
之间(.
与->
除外,以及指针可能为NULL
)
cProtocoland
制作副本(如果它不是抽象的,它会),并切掉所有派生的功能。 rProtocol
使用其他一些对象,并使其保持多态。 pProtocol
可让您更灵活地分配或重新分配,以及分配NULL
。作为交换,您需要NULL
- 检查指针,并可选择在复制构造函数,赋值运算符等中管理与其关联的资源。
如果我没有在构造函数中初始化
rProtocol
怎么办?这会编译吗?它包含什么?由于无法使用默认值进行实例化!?
如果无法在构造函数中初始化引用,则根本不能使用该成员的引用:指针成为您唯一的选择。