cam*_*ino 7 c++ virtual overriding function
我遇到了关于覆盖虚函数的问题,实际上,它是关于hessian(一种Web服务协议).
它有一个基类Object和一些派生类:Long,Int,String,...,所有派生类都有一个无虚函数"value"
class Object
{
...
};
class Long :public Object
{
...
public:
typedef long long basic_type;
basic_type value(){return value_;}
private:
basic_type value_;
...
};
class Int :public Object
{
...
public:
typedef int basic_type;
basic_type value(){return value_;}
private:
basic_type value_;
...
};
Run Code Online (Sandbox Code Playgroud)
现在我想添加一个函数,比如toString,它可以将Object转换为字符串:
Object *obj = ...
cout<<obj->toString();
Run Code Online (Sandbox Code Playgroud)
如果我可以将值函数更改为virtual,我只需要在Object中编写一个toString函数,否则,我需要编写一个虚函数toString,并在所有派生类中重写这个函数.
例如
class Object
{
virtual Type value(); // It seemed that I can't write a function like this,because the Type is different for different derived classes
std::string toString()
{
some_convert_function(value());
}
};
Run Code Online (Sandbox Code Playgroud)
但我不能写一个虚值函数,因为返回值不能被覆盖.
这个问题有什么好的解决方案吗?
谢谢
仅以非常有限的方式,在(原始)指针或引用返回类型中可以是协变的.
嗯,有两个相当不错的解决方案,一个稍微不好的解决方案.
我在这里给你一个稍微不好的解决方案.我给出的一个原因是它很容易理解,或者至少它很容易"复制和修改",即使一个人不太了解它.另一个原因是,其中一个好的解决方案需要一些广泛的通用支持机制,这里没有讨论的余地,另一个好的解决方案(我认为几乎在所有方面都是最好的解决方案)是至少一种,至少当我提出这种解决方案时,已经自动收到了驱动器的支持,只有那个,这里就是SO.我猜这是为这里的多样性付出的代价,多样性是一件非常好的事情:-)但不幸的是,这意味着提供真正的好东西是没有意义的,那么我就会接受负面的代表.
无论如何,代码,基于虚拟继承的优势; 它与在Java或C#中继承接口的实现大致相同:
#include <iostream>
#include <string>
#include <sstream>
//--------------------------------------- Machinery:
class ToStringInterface
{
public:
virtual std::string toString() const = 0;
};
template< typename ValueProvider >
class ToStringImpl
: public virtual ToStringInterface
{
public:
virtual std::string toString() const
{
ValueProvider const& self =
*static_cast<ValueProvider const*>( this );
std::ostringstream stream;
stream << self.value();
return stream.str();
}
};
//--------------------------------------- Usage example:
class Object
: public virtual ToStringInterface
{
// ...
};
class Long
: public Object
, public ToStringImpl< Long >
{
public:
typedef long long BasicType;
Long( BasicType v ): value_( v ) {}
BasicType value() const { return value_; }
private:
BasicType value_;
};
class Int
: public Object
, public ToStringImpl< Int >
{
public:
typedef int BasicType;
Int( BasicType v ): value_( v ) {}
BasicType value() const { return value_; }
private:
BasicType value_;
};
int main()
{
Object const& obj = Int( 42 );
std::cout << obj.toString() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如果你Long和Int类等非常相似,就像它们看起来那样,考虑只定义一个类模板,或者可能继承这种模板的特化(这也可能有助于避免错误,因为它减少了冗余).
编辑:我现在看到你已经接受了一个答案,这个答案基本上只是我关于模板的最后一个建议.这意味着我已经回答了所提出的问题(针对不同类别的不同类别的解决方案),而你的内容则不那么通用.那好吧.
干杯&hth.,
不,您不能使用虚拟“值”函数在 Object 中写入 toString 并覆盖返回类型。然而,您可以编写一个虚拟的 toString 并使用模板编程技巧完成几乎相同的事情。
class Object
{
public:
virtual std::string toString();
}
template < class ValueType >
class BasicType : Object
{
public:
typedef ValueType basic_type;
basic_type value() { return value_; }
std::string toString()
{
return some_convert_function( value_ );
}
private:
basic_type value_;
}
typedef BasicType<long long> Long;
typedef BasicType<int> Int;
Run Code Online (Sandbox Code Playgroud)