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;
}
ellipse 图1 返回基类类型 ellipse 图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();
};
Reference

HOWTO: Covariant Return Types in C++

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


当前题目:WHYTO:CovariantReturnTypesinC++-创新互联
网页链接:http://pwwzsj.com/article/disooi.html