[英]operator++(int) overload with abstract base class and Wall
我目前正在創建一組迭代器,它們的實現細節會有所不同,但會在相同的算法中使用。 因此,它們必須具有相同的接口。 為此,我創建了一個抽象迭代器類,並在所有其他迭代器中繼承此類。
這應該可以讓您了解我的代碼是什么樣的:
class INodeIterator
{
public:
virtual ~INodeIterator() {};
virtual bool operator!= (const INodeIterator& other) =0;
virtual bool operator== (const INodeIterator& other) =0;
virtual INodeIterator& operator++ () =0;
virtual INodeIterator& operator++ (int i) =0;
virtual Node& operator* () =0;
};
class NodeIterator : public INodeIterator
{
public:
/* snip */
NodeIterator& operator++ (int i)
{
NodeIterator tmp(*this);
++(*this);
return(tmp);
}
};
現在我遇到了與迭代器中的C ++后增量運算符重載相同的問題(使用-Wall -Werror進行編譯) :我的operator ++(int)實現拋出一個警告(gcc 4.8.0),返回對臨時的引用。 鏈接問題中的解決方案是僅返回對象而不是引用。
但是,這對我不起作用。 如果我更改接口和派生類以返回對象而不是引用,則會出現以下錯誤(摘錄,刪除其他文件名等):
INodeIterator.h:16:27: error: invalid abstract return type for member function ‘virtual INodeIterator INodeIterator::operator++(int)’
virtual INodeIterator operator++ (int i) =0;
^
NodeIterator.h:33:22: error: invalid covariant return type for ‘virtual NodeIterator NodeIterator::operator++(int)’
NodeIterator operator++ (int i);
^
INodeIterator.h:16:27: error: overriding ‘virtual INodeIterator INodeIterator::operator++(int)’
virtual INodeIterator operator++ (int i) =0;
^
將派生類的返回類型更改為對象但不在抽象類上更改會返回“指定的沖突返回類型”錯誤。
我怎樣才能做到這一點?
嘗試更改設計:讓NodeIterator將INodeIterator作為指針。 NoteIterator的所有方法都將委托給持有的INodeIterator對象。 在這種情況下,您可以使用正確的簽名:
struct IteratorInterface {
virtual ~IteratorInterface() {}
virtual std::unique_ptr<IteratorInterface> clone() const = 0;
virtual void next() = 0;
};
class Iterator {
std::unique_ptr<IteratorInterface> impl;
public:
Iterator(std::unique_ptr<IteratorInterface> r) : impl(std::move(r)) {}
Iterator(const Iterator &r) : impl(r.impl->clone()) {}
Iterator& operator++() {
impl->next();
return *this;
}
Iterator operator++(int ) {
Iterator tmp(*this);
impl->next();
return tmp;
}
void swap(Iterator &other) {
other.impl.swap(impl);
}
};
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
struct IteratorInterfaceImpl : IteratorInterface {
int i;
IteratorInterfaceImpl() : i(0) {}
virtual std::unique_ptr<IteratorInterface> clone() const {
return std::unique_ptr<IteratorInterface>(new IteratorInterfaceImpl(*this));
}
virtual void next() {
i += 1;
}
};
Iterator tmp(std::unique_ptr<IteratorInterface>(new IteratorInterfaceImpl()));
tmp++;
++tmp;
return 0;
}
我能想到的唯一理智的方法是從INodeIterator::operator++(int)
返回void
- 即沒有。
您不能從后增量運算符返回引用,因為您必須創建一個實際對象(存儲前一個值),並返回一個引用。 這個對象要么是動態分配的,要么必須被銷毀(必須在返回的引用上顯式調用delete
),或者它是operator++(int)
的“局部變量”,並在返回之前被銷毀:
virtual NodeIterator& operator++(int)
{
NodeIterator prev_value(*this);
++(*this);
return prev_value; // dangling/invalid reference, `prev_value` is destroyed
}
virtual NodeIterator& operator++(int)
{
NodeIterator* pPrev_value = new NodeIterator(*this);
++(*this);
return *pPrev_value; // have to explicitly call delete on the returned ref...
}
您也無法從INodeIterator::operator++(int)
返回INodeIterator
類型的對象,因為它是一個抽象類。
你得到錯誤的原因
INodeIterator.h:16:27: error: invalid abstract return type for member function ‘virtual INodeIterator INodeIterator::operator++(int)’
virtual INodeIterator operator++ (int i) =0;
是因為您的純虛函數返回一個抽象類對象。
一種解決方案是使用new運算符並返回在堆中創建的對象,這是安全的。
virtual INodeIterator& operator++ (int i) =0;
NodeIterator& operator++ (int i)
{
NodeIterator* tmp = new NodeIterator (*this);
++(*this);
return(*tmp);
}
你的原型是不正確的。 它應該是
NodeIterator operator++ (int i)
也就是說,刪除引用返回,否則你將返回對超出范圍的東西的引用(你的tmp
)不是一個好主意!
編譯器在讓你知道這一點方面非常有幫助!
我不知道你想聽到什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.