返回对类的引用
returning reference to class
我有这样的代码:
#include <stdio.h>
class AbstractIterator{
virtual void do_something() = 0;
};
class AbstractList{};
class Iterator : public AbstractIterator{
public:
Iterator(const AbstractList & list) : list(list){};
virtual void do_something() override{
printf("hellon");
};
const AbstractList & list;
};
class List : public AbstractList{
public:
Iterator getIterator(){
return Iterator(*this);
}
};
int main(int argc, char** argv){
List list;
Iterator it = list.getIterator();
it.do_something();
return 0;
}
这是可行的,但我想将getIterator()方法"推"到AbstractList类中。要做到这一点,需要能够做到以下几点:
/* non const */
AbstractIterator &it = list.getIterator();
it.do_something();
这有可能在没有动态分配的情况下以某种方式实现吗?
也许这个
class AbstractIterator{
public:
virtual void do_something() = 0;
};
class AbstractList
{
public:
virtual AbstractIterator* getIterator() = 0;
};
class Iterator : public AbstractIterator{
public:
Iterator(AbstractList& list) : list(list){}
const Iterator operator=( const Iterator& other )
{
list = other.list;
return *this;
}
virtual void do_something() override{
printf("hellon");
}
AbstractList& list;
};
class List : public AbstractList{
Iterator iterator;
public:
List() : iterator( *this ) {}
AbstractIterator* getIterator() override
{
iterator = Iterator( *this );
return &iterator;
}
};
int main(int argc, char *argv[])
{
List list;
AbstractIterator* it = list.getIterator();
it->do_something();
return 0;
}
顺便说一句。重要的是要记住迭代器的有效性(修改列表、虚拟析构函数等),这个例子非常基本:)
这是写得很快的
- 迭代器的无效函数应该是私有的,可以这样做,但会使源代码复杂化
- 注意,iterface方法是由template方法调用的-好习惯
来源:
class AbstractList;
class AbstractIterator{
public:
AbstractIterator( AbstractList* list ) : list( list ), valid( true ) {}
virtual bool moveNext() = 0;
void doSomething()
{
if( isValid() )
{
do_something();
}
}
bool isValid() { return valid && 0 != list; }
void invalidate()
{
valid = false;
}
protected:
AbstractList* list;
private:
virtual void do_something() = 0;
bool valid;
};
class AbstractList
{
public:
virtual ~AbstractList()
{
for( std::shared_ptr< AbstractIterator > it : iterators )
{
it->invalidate();
}
iterators.clear();
}
std::shared_ptr< AbstractIterator > iterator()
{
std::shared_ptr< AbstractIterator > it = getIterator();
iterators.push_back( it );
return it;
}
private:
virtual std::shared_ptr< AbstractIterator > getIterator() = 0;
private:
std::list< std::shared_ptr< AbstractIterator > > iterators;
};
class Iterator : public AbstractIterator{
public:
Iterator( AbstractList* list ) : AbstractIterator(list){}
~Iterator() {printf("Iterator cleanedn");}
virtual bool moveNext() override
{
if( !isValid() )
{
return false;
}
//do ...... iterate ... whatever
return true;
}
virtual void do_something() override
{
printf("hellon");
}
};
class List : public AbstractList{
public:
~List()
{
printf("List cleanedn");
}
List() {}
private:
std::shared_ptr< AbstractIterator > getIterator() override
{
std::shared_ptr< AbstractIterator > iterator( new Iterator( this ) );
return iterator;
}
};
int main(int argc, char *argv[])
{
List* list = new List();
std::shared_ptr< AbstractIterator > it = list->iterator();
it->doSomething();
if( it->isValid() )
{
std::cout << "It valid" << std::endl;
}
delete list;
if( !it->isValid() )
{
std::cout << "It !valid" << std::endl;
}
return 0;
}
这更不像
另一种解决方案可能是:
class AbstractIteratorImpl{
public:
virtual void do_something() = 0;
};
class Iterator {
pibluc:
void do_something() { impl->do_something(); }
friend class AbstractList;
private:
Iterator( std::unique_ptr<AbstractIteratorImpl> &limpl ) : impl( limpl ){}
std::unique_ptr<AbstractIteratorImpl> impl;
}
class AbstractList
{
virtual std::unique_ptr<AbstractIteratorImpl> getIteratorImpl() = 0;
public:
Iterator getIterator() { return Iterator( getIteratorImpl() ); }
};
我不确定所有的参数/返回类型都是正确的,但我希望这个想法是清楚的。
PS当然,如果你想在容器中保留迭代器的所有权,你可以使用std::shared_ptr
,也可以在Iterator
中保留std::weak_ptr
,并且你不必显式地实现invalidate()
,这将是自动魔术。
我想你的意思是对抽象类类型对象的非常数引用(与Java相比,C++没有接口,它们只是纯粹的抽象类)。
要返回引用,对象必须在某个地方保持活动状态。因此,如果您的AbstractList
是一个接口(仅限抽象方法),我将不知道如何做到这一点。
相关文章:
- 如何通过引用返回对象
- 函数如何使用引用返回所需的数字?
- 如何防止引用返回的私有结构的突变
- 如何在不使用临时变量的情况下取消引用返回指针的函数的返回值?
- 通过引用返回的变量的范围
- 对于具有引用返回类型的搜索算法,默认返回值应该是什么?
- 运算符重载C++类中的引用返回
- C++对象引用返回不同的值
- 解释通过从函数引用返回数组的语法
- 具有引用返回类型的重写方法上的协变返回类型无效
- 为什么在通过引用返回运算符分配时取消引用'this'指针?
- 为什么我在函数中使用引用并通过引用返回它仍然有效?
- 直接在 C++ 中将值分配给引用返回类型
- C++当您取消引用指向类对象的指针,然后将其作为引用返回时,是否可以对此引用调用方法
- 可以通过常量引用返回默认参数的值吗?
- 按值与右值引用返回
- 非常量引用返回函数在常量值返回函数上用作 r 值
- 当我使用按引用返回时,我不知道这些代码之间的区别
- 为什么通过引用返回向量比通过移动返回要快得多?
- 通过引用返回包含对象的向量