何为(is-a)?
也就是能执行在Base-class(基类)身上的操作,都能执行在Derived-class身上,但是能执行在Derived-class身上的操作并不一定能执行在Base-class上面.
case 1: 在抽象基类中声明并且实现纯函数,派生类中不再实现,此时无论是派生类还是基类都不能作为对象,否则就会报错.
#include <iostream>
class Base {
public:
Base() = default;
Base(const int& val) :value(val) {}
Base(const Base& other) :value(other.value) {}
Base(Base&& other) :value(other.value) {}
Base& operator=(const Base& other)
{
this->value = other.value;
return *this;
}
Base& operator=(Base&& other)
{
this->value = other.value;
return *this;
}
virtual ~Base() = default; //注意这里作为基类的情况下必须把构造函数作为虚函数.
//在析构函数调用的时候就能保证析构正确的内容.
virtual void print()const //virtual function
{
std::cout << this->value << std::endl;
}
void word(const int& number)const //!
{
std::cout << number << std::endl;
}
private:
int value{ 10 }; //在调用默认构造函数的情况下会调用这里的初始化语句.
};
class PureBase { //由于有 pure virtual function因此该class并不能当对象使用.
public:
virtual ~PureBase() = default;
virtual void pureVirFunc()const = 0; //pure virtual function!
protected: //注意我们都定义为了: protected
//因为由于含有pure virtual function, 因此我们不能使用PureBase,把下面的函数都定义为protected的更加合适.
PureBase() = default;
PureBase(const int& num) :number(num),theNum(num+10) {}
//PureBase(const PureBase& other) :number(other.number), theNum(other.theNum){}
//PureBase(PureBase&& other) :number(other.number), theNum(other.theNum) {}
//const PureBase& operator=(const PureBase& other)
//{
// this->number = other.number;
// this->theNum = other.theNum;
// return *this;
//}
//const PureBase& operator=(PureBase&& other)
//{
// this->number = std::move(other.number);
// this->theNum = std::move(other.theNum);
// return *this;
//}
const int& getPrivateData()const
{
return (this->theNum);
}
int& getPrivateData()
{
return (this->number);
}
template<typename T>
void setData(T&& number)
{
this->theNum = std::forward<T>(number);
}
int number{ 20 }; //注意数据这里也是: protected的.
//为了给派生类可见,而且确保派生类能够修改派生来的数据.
private:
int theNum{ 30 };
};
void PureBase::pureVirFunc()const //注意这里我们给上面的 pure virtual function 提供了定义.
{ //为什么要提供定义呢! 因为需要访问PureBase的private的成员.
std::cout << "pureVirtualFunction In PureBase: " << this->theNum << std::endl;
}
class DerivedOne : public Base, public PureBase {
public:
DerivedOne() = default;
DerivedOne(const int& v) : Base(v), PureBase(v), data(v) {}//注意这里我们使用了: 基类中的protected的构造函数.
virtual ~DerivedOne() = default;
DerivedOne(const DerivedOne& other)
:Base(other),
data(other.data)
{
this->number = other.number;
this->setData(other.getPrivateData());
//PureBase::PureBase(other); //由于PureBase是个abstract-class因此并不能使用.
}
DerivedOne(DerivedOne&& other)
:Base(other),
data(other.data)
{
this->number = other.number;
this->setData(std::move(other.getPrivateData()));
}
DerivedOne& operator=(const DerivedOne& other)
{
Base::operator=(other);
this->number = other.number;
this->setData(other.getPrivateData());
return *this;
}
DerivedOne& operator=(DerivedOne&& other)
{
Base::operator=(other);
this->number = std::move(other.number);
this->setData(std::move(other.getPrivateData()));
return *this;
}
virtual void pureVirFunc()const override
{
std::cout << "pureVirtualFunction In Derived Class: " << this->data << std::endl;
}
virtual void print()const override
{
std::cout << "DerivedOne-class: " << this->number << std::endl;
}
void print(const int& theVal, int rightVal)const //注意这里,并不会影响虚函数的动态调用.
{
rightVal = 100;
int x{};
x = 200;
std::cout << "theVal: " << theVal << std::endl;
}
void word()const //这里会覆盖继承而来的: 所有同名的函数,不管参数返回类型如何, 只要函数名字一样就会被覆盖.
{
std::cout << "therWordInDerivedClass" << std::endl;
}
private:
int data{ 40 };
};
int main()
{
Base base{};
DerivedOne derived;
//case 1: 不能创建一个abstract-class作为对象.
//PureBase pureBase{};
//case 2: 可以作为动态调用的对象.
PureBase& pB{ derived };
pB.pureVirFunc();
//case 3
DerivedOne de{ 40 };
derived = de;
//case 4: 派生类的同名函数隐藏了,基类中的同名函数,不管返回类型,还有参数如何.
derived.word();
//derived.word(20); //error!
derived.Base::word(20); //但是我们可以强制调用.
return 0;
}
case2: 基类向派生类转换其中 只有派生类中基类部分被初始化了, 派生类自己的部分处于未定义状态.
#include <iostream>
#include <string>
class Base{
private:
int number_;
public:
explicit Base(const int& n_):number_(n_){}
virtual ~Base()=default;
virtual void print()const
{
std::cout<<this->number_<<std::endl;
}
void set_number()noexcept
{
this->number_ = 1;
}
};
class InheritBase : public Base{
private:
std::string str_;
public:
InheritBase()=default;
InheritBase(const int& number_, const std::string& s_):Base(number_),str_(s_){}
void println()const
{
std::cout<<this->str_<<std::endl;
}
~InheritBase()=default;
};
int main()
{
Base* ptr_b = new InheritBase(520, "shihuawoaini");
ptr_b->set_number();
ptr_b->print();
Base* ptr_b2 = new Base(100);
InheritBase* ptr_i = static_cast<InheritBase*>(ptr_b2);
//ptr_i->println(); //虽然可以运行但是会在运行中出错,因为InheritBase中的部分是未被初始化的.
ptr_i->print();
delete ptr_b2;
delete ptr_b;
return 0;
}