WHYTO:CovariantReturnTypesinC++-创新互联
在类的继承中为什么要返回协变类型?原因之一是使用协变时对用户友好👬,不用在类型之间强转。详见如下示例。
我们提供的服务有:成都网站设计、网站建设、微信公众号开发、网站优化、网站认证、巢湖ssl等。为上千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的巢湖网站制作公司test_covariant_return_types0.hpp
返回基类类型
#pragma once
#includenamespace test_covariant_return_types0
{class Base
{public:
Base()
{num_ = new int(0);
++num_ct_;
std::cout<< "Base ctor called."<< std::endl;
}
Base(const Base& b)
{num_ = new int(*b.num_);
++num_ct_;
std::cout<< "Base copy-ctor called."<< std::endl;
}
Base& operator=(const Base& b)
{ *(this->num_) = *(b.num_);
std::cout<< "Base copy-assign-operator called."<< std::endl;
}
virtual Base* clone() const
{ std::cout<< "Base clone called."<< std::endl;
return new Base(*this);
}
~Base()
{ if(num_)
{ --num_ct_;
delete num_; num_ = nullptr;
}
std::cout<< "Base dtor called."<< std::endl;
}
private:
int* num_;
public:
static int num_ct_;
};
int Base::num_ct_ = 0;
class Derived : public Base
{public:
Derived()
{ flag_ = new char('x');
++num_flag_ct_;
std::cout<< "Derived ctor called."<< std::endl;
}
Derived(const Derived& d)
{flag_ = new char(*d.flag_);
++num_flag_ct_;
std::cout<< "Derived copy-ctor called."<< std::endl;
}
Derived& operator=(const Derived& d)
{*(this->flag_) = *(d.flag_);
std::cout<< "Derived copy-assign-operator called."<< std::endl;
return *this;
}
virtual Base* clone() const
{ std::cout<< "Derived clone called."<< std::endl;
return new Derived(*this);
}
~Derived()
{ if(flag_)
{ delete flag_; flag_=nullptr;
--num_flag_ct_;
}
std::cout<< "Derived dtor called."<< std::endl;
}
private:
char* flag_;
public:
static int num_flag_ct_;
};
int Derived::num_flag_ct_ = 0;
auto main()->void
{ std::cout<< "test covariant return types......."<< std::endl;
Derived* d = new Derived;
Base* b = d->clone();
Derived* d2 = dynamic_cast(b);
delete d; d = nullptr;
delete b; b = nullptr; // 获取到的是b,就应该delete b,而不是d2,此时导致资源释放不完全
std::cout<< (Base::num_ct_? "Warning, ":"")<< Base::num_ct_<< " num_ in Bass not released!"<< std::endl;
std::cout<< (Derived::num_flag_ct_? "Warning, ":"")<< Derived::num_flag_ct_<< " flag_ in Derived not released!"<< std::endl;
std::cout<< "test covariant return types pass"<< std::endl;
}
}
test_covariant_return_types1.hpp
返回协变类型
#pragma once
#includenamespace test_covariant_return_types1
{class Base
{public:
Base()
{num_ = new int(0);
++num_ct_;
std::cout<< "Base ctor called."<< std::endl;
}
Base(const Base& b)
{num_ = new int(*b.num_);
++num_ct_;
std::cout<< "Base copy-ctor called."<< std::endl;
}
Base& operator=(const Base& b)
{ *(this->num_) = *(b.num_);
std::cout<< "Base copy-assign-operator called."<< std::endl;
}
virtual Base* clone() const
{ std::cout<< "Base clone called."<< std::endl;
return new Base(*this);
}
~Base()
{ if(num_)
{ --num_ct_;
delete num_; num_ = nullptr;
}
std::cout<< "Base dtor called."<< std::endl;
}
private:
int* num_;
public:
static int num_ct_;
};
int Base::num_ct_ = 0;
class Derived : public Base
{public:
Derived()
{ flag_ = new char('x');
++num_flag_ct_;
std::cout<< "Derived ctor called."<< std::endl;
}
Derived(const Derived& d)
{flag_ = new char(*d.flag_);
++num_flag_ct_;
std::cout<< "Derived copy-ctor called."<< std::endl;
}
Derived& operator=(const Derived& d)
{*(this->flag_) = *(d.flag_);
std::cout<< "Derived copy-assign-operator called."<< std::endl;
return *this;
}
virtual Derived* clone() const override // 返回协变类型
{ std::cout<< "Derived clone called."<< std::endl;
return new Derived(*this);
}
~Derived()
{ if(flag_)
{ delete flag_; flag_=nullptr;
--num_flag_ct_;
}
std::cout<< "Derived dtor called."<< std::endl;
}
private:
char* flag_;
public:
static int num_flag_ct_;
};
int Derived::num_flag_ct_ = 0;
auto main()->void
{ std::cout<< "test covariant return types......."<< std::endl;
Derived* d = new Derived;
Derived* d2 = d->clone(); // 返回协变获取到的直接是Derived*类型
delete d; d = nullptr;
delete d2; d2 = nullptr; // delete直接获取到的类型Derived*,保障资源释放完全
std::cout<< (Base::num_ct_? "Warning, ":"")<< Base::num_ct_<< " num_ in Bass not released!"<< std::endl;
std::cout<< (Derived::num_flag_ct_? "Warning, ":"")<< Derived::num_flag_ct_<< " flag_ in Derived not released!"<< std::endl;
std::cout<< "test covariant return types pass"<< std::endl;
}
}
main.cpp
#include "test_covariant_return_types0.hpp"
#include "test_covariant_return_types1.hpp"
#includeint main()
{std::cout<< "__cplusplus: "<< __cplusplus<< std::endl;
test_covariant_return_types0::main();
std::cout<< std::string(40,'-')<< std::endl;
test_covariant_return_types1::main();
std::cout<< std::string(40,'-')<< std::endl;
}
图1 返回基类类型
图2 返回协变类型输出:
__cplusplus: 201703
test covariant return types.......
Base ctor called.
Derived ctor called.
Derived clone called.
Base ctor called.
Derived copy-ctor called.
Derived dtor called.
Base dtor called.
Base dtor called.
0 num_ in Bass not released!
Warning, 1 flag_ in Derived not released!
test covariant return types pass
----------------------------------------
test covariant return types.......
Base ctor called.
Derived ctor called.
Derived clone called.
Base ctor called.
Derived copy-ctor called.
Derived dtor called.
Base dtor called.
Derived dtor called.
Base dtor called.
0 num_ in Bass not released!
0 flag_ in Derived not released!
test covariant return types pass
----------------------------------------
返回的协变类型也可以是除了成员函数所在的类类型之外的类型
class NetServer {public:
virtual NetClient* acceptConnection() = 0;
};
class NetServerTCP : public NetServer {public:
virtual NetClientTCP* acceptConnection();
};
class NetServerSCTP : public NetServer {public:
virtual NetClientSCTP* acceptConnection();
};
ReferenceHOWTO: Covariant Return Types in C++
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
名称栏目:WHYTO:CovariantReturnTypesinC++-创新互联
分享URL:http://ybzwz.com/article/disooi.html