前言
笔者工作中有很多类派生自一个虚基类
,但是这些派生类
又有很多操作是大致相同,尤其是这些类都不能拷贝
,所以需要删除拷贝构造函数
和拷贝赋值运算符
。最直接的想法是在虚基类
里面删除拷贝构造函数
和拷贝赋值运算符
。但我想因为虚基类
不能实例化
,那是否可以定义常规构造函数
、移动构造函数
、移动赋值运算符
呢?经过验证得到了答案。
结果:
虚基类
中能
定义常规构造函数
、移动构造函数
、移动赋值运算符
,能删除拷贝构造函数
和拷贝赋值运算符
。- 因为是
虚基类
,含有未实现
的纯虚函数
,故不能被外部(非派生类)直接实例化,但能被派生类实例化
。派生类构造时能调用虚基类的构造函数。 - 需要注意的是,因为虚基类删除了拷贝构造函数和拷贝赋值运算符,则需要
手动定义所需
构造函数(派生类需要用到的
),否则编译不通过。派生类可以不定义构造函数来让编译器生成默认构造函数,否则需要手动定义出构造函数。这点值得进一步讨论
。
示例代码
#include <atomic>
#include <thread>
#include <functional>
#include <iostream>
#include <map>
#include <unordered_map>
#include <memory>
#include <mutex>
class Interface {
public:
Interface() {
std::cout << "Interface::Interface() " << this << std::endl;
}
Interface(Interface&&) {
std::cout << "Interface::Interface(&&) " << this << std::endl;
}
Interface& operator = (Interface&&) {
std::cout << "Interface::operator = () " << this << std::endl;
return *this;
}
Interface(const Interface&) = delete;
Interface& operator = (const Interface&) = delete;
virtual ~Interface() {
std::cout << "Interface::~Interface() " << this << std::endl;
}
virtual void VirtualFunc() = 0;
};
class Base : public Interface {
public:
/*
// 让编译器自动生成
Base() {
std::cout << "Base::Base()" << std::endl;
}
~Base() {
std::cout << "Base::~Base()" << std::endl;
}
*/
virtual void VirtualFunc() {
std::cout << "Base::VirtualFunc " << this << std::endl;
}
private:
std::string s_;
};
int main(int argc, char* argv[]) {
Base b;
Base xx = std::move(b);
// Base cc = b; //无法编译通过,拷贝已删除
b.VirtualFunc();
xx.VirtualFunc();
return 0;
}
运行结果
Interface::Interface() 000000C69F0FF9E8
Interface::Interface(&&) 000000C69F0FFA38
Base::VirtualFunc 000000C69F0FF9E8
Base::VirtualFunc 000000C69F0FFA38
Interface::~Interface() 000000C69F0FFA38
Interface::~Interface() 000000C69F0FF9E8
结尾
日常想法问题记录。如果觉得还不错,你的关注点赞加收藏便是笔者更新的最大动力^_^
。