gpt4 book ai didi

具有纯虚运算符+函数的 C++ 抽象基类

转载 作者:行者123 更新时间:2023-11-30 02:50:00 25 4
gpt4 key购买 nike

假设我正在创建一个抽象基类来定义一个公共(public)接口(interface)。我希望 operator+ 成为这个公共(public)界面的一部分。这似乎在 C++ 中是不可能的,或者我遗漏了一些东西。

例如,假设下面的代码是一个 .h 文件,声明了名为 IAbstract 的抽象基类的公共(public)接口(interface)。此代码无法编译,因为我无法声明返回抽象基类实例的函数。这个编译错误是有道理的,但我不明白的是:Is there any way to guarantee operator+ will exist in the public interface of IAbstract?

#include <iostream>

// An abstract base class
class IAbstract
{
public:
IAbstract(int value);
virtual ~IAbstract() {}
virtual int SomeOtherFunction() =0;

//This is ok
virtual IAbstract& operator++() =0;

//This will not compile
virtual const IAbstract operator+(const IAbstract& rhs) =0;
//Xcode5 says "Semantic Issue: Return type 'IAbstract' is an abstract class"
};

最佳答案

除了按值返回问题之外,您设计的真正问题是C++ 语言的工作方式

Java 等面向对象的语言通过类层次结构、接口(interface)和多态性定义和传输功能。您的代码就是典型的例子。
C++ 不以这种方式工作。 C++ 通过抽象概念定义功能,类只需要实现这些概念就可以以某种方式使用。一个类如何/是否遵循或实现某个概念取决于它的行为、某些功能的实现(如重载运算符)等。

因此,C++ 实现您想要实现的目标的方法是以通用方式重载所需的运算符,以确保将实现该概念的所有类都可以使用它
换句话说,如果你试图做一个可添加的概念,即表示可以与其他添加的东西,一个类只需要重载operator+。如果一个类重载了 operator+ 它的 addable。很简单。

这是另一个例子:std::copy() 的经典实现:

template<typename IT , typename DEST_IT>
void copy( IT begin , IT end , DEST_IT dest_begin )
{
while( begin != end )
*dest_begin++ = *begin++;
}

在该实现中,beginend 的类型是什么? 简单的回答:我们不知道。可以是任何东西。 但可以是任何必须满足我们的功能要求 的东西,即:可取消引用、可递增和可比较。换句话说:它是一个 可迭代 类型。一种可以(并且看起来像)迭代器的类型。

因此 std::copy() 适用于由可迭代对象表示的任何范围。可以是数组:

int main()
{
int a[] = { 1,2,3 };
int b[3];

int* begin_a = &a[0];
int* end_a = &a[2];
int* begin_b = &b[0];

//Pointers are an iterable thing, right?:
std::copy( begin_a , end_a , begin_b );

//Or just the common generic way (Which does exactly the same):
std::copy( std::begin( a ) , std::end( a ) , std::begin( a ) );
}

vector 、列表等:

int main()
{
std::vector<int> a = { 1,2,3 };
std::vector<int> b;

//Wooh, the code is exactly the same! Thats why templates are cool.
std::copy( std::begin( a ) , std::end( a ) , std::begin( a ) );
}

更多奇怪的东西,比如遍历流的迭代器:

int main()
{
std::vector<int> a = { 1,2,3 };

//Copy a vector to the standard output? Yes we can!
std::copy( std::begin( a ) , std::end( a ) , std::ostream_iterator<int>( std::cout , "\n" ) );
}

1
2
3

还有你自己的类(class):

struct numeric_iterator
{
int value;

numeric_iterator( int initial_value = 0 ) : value( initial_value ) {}

//numeric_iterator is an iterable thing because...

//... its dereferenciable
int operator*() const
{
return value;
}

//... its incrementable
numeric_iterator& operator++()
{
++value;
return *this;
}

numeric_iterator operator++(int)
{
numeric_iterator copy( *this );

++(*this);

return copy;
}

//... and its comparable
friend bool operator==( const numeric_iterator& lhs , const numeric_iterator& lhs )
{
return lhs.value == rhs.value;
}

friend bool operator!=( const numeric_iterator& lhs , const numeric_iterator& lhs )
{
return !( lhs == rhs );
}
};

int main()
{
//Tah dah!
std::copy( numeric_iterator( -4 ) ,
numeric_iterator( 5 ) ,
std::ostream_iterator<int>( std::cout , " " )
);
}

-4 -3 -2 -1 0 1 2 3 4

关于具有纯虚运算符+函数的 C++ 抽象基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20831278/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com