c++ - vritually virtual new

Let's see what if we want to clone some thing when virtual and class hierarchy is considered.

 

 

// it is ok if we know in advance what is the type of object we are cloning.
NotQuery *pnq;
NotQuery *pnq2 = new NotQuery(*pnq);

// however what if the object type we don't know
const Query* pq = pnq->op() ; // suppose that pnq-> returns some Query instance.
const Query * pq3 = new ???(*pq);

 

So, why not create anthor function which is called clone, which is virtual and each derived  class know how to create it self. 

 

 

so we have the following code.

 

 

class Query
{
public:
	virtual Query* clone() = 0;
};

class NameQuery : public Query
{
public:
	NameQuery(string name) : _name(name) { }
	NameQuery(const NameQuery &rhs) : _name(rhs._name) {}
	virtual Query* clone()
		// invokes the NameQuery constructor
	{ return new NameQuery(*this); }

private:
	string _name;
};

 

You see in this impl, we have a clone method which return Query * pointer.  and you will probably use the code as below. 

 

void test_virtually_virtual_new()
{
	Query *pq = new NameQuery("Rike");
	// so this is not working as the 
	// Query::clone() returns Qeury
	//NameQuery * pq2 = pq->clone();
	NameQuery *pnq2 = static_cast<NameQuery *> (pq->clone());
	// but why this is needed of the static cast?
	NameQuery *pnq3 = static_cast<NameQuery *>(pnq2->clone());
}

 

this is not neat, expecially when we already have  a NameQuery poiter, we have to do the downcast...

 

But remember we have discussed there is an exception to the function signature mismatch, where virtual function can have different return types in the base and in the derived class.

 

Here is how we reimplemented it. 

 

class NameQuery : public Query
{
public:
	NameQuery(string name) : _name(name) { }
	NameQuery(const NameQuery &rhs) : _name(rhs._name) {}
	//virtual Query* clone()
	//	// invokes the NameQuery constructor
	//{ return new NameQuery(*this); }

	// while the following is what you should do
	virtual NameQuery *clone()
	{
		return new NameQuery(*this); 
	}
private:
	string _name;
};

 

Now, we can use the virtual new as follow.

 

 

void test_virtually_virtual_new_return_overloaded()
{
	Query *pq = new NameQuery("Rike");
	NameQuery* pnq2 = static_cast<NameQuery *> (pq->clone());
	// there is no need to do the static_cast as you saw before. 
	//
	NameQuery* pnq3 = pnq2->clone();

}
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值