在下面的代码中,IContainer
是一个纯抽象类:它不包含任何非纯虚方法。在这种情况下,我不希望能够实例化IContainer
类型的对象,但是我希望能够在IContainer*
中保存派生类的实例。
在下面的main
中,我创建了一些实现SimpleContainer
的具体类IContainer
的实例。接下来,我在一些SimpleContainer
变量中存储了指向这些IContainer*
的指针。
这是我的问题:由于IContainer
是一个抽象类,我无法实例化它。但是,在main
的底部,您可以看到我取消引用我的IContainer
指针以检查相等性。为什么我能这样做?另外,iCont1 == iCont2
和*iCont1 == *iCont2
之间是否存在差异?
#include <iostream>
class IContainer{
public:
virtual bool operator==(const IContainer& aICont) const = 0;
virtual int getVal() const = 0;
};
class SimpleContainer : public IContainer{
public:
SimpleContainer(int val) : val(val){};
int getVal() const override {return val;}
bool operator==(const IContainer& aICont) const override
{
return val == aICont.getVal();
}
private:
int val;
};
int main(){
SimpleContainer cont1(1), cont2(2), cont3(1);
IContainer* iCont1 = &cont1;
IContainer* iCont2 = &cont2;
IContainer* iCont3 = &cont3;
std::cout << "iCont1 == iCont2 -> " << (iCont1 == iCont2 ? "true" : "false") << " || Expecting -> " << "false" << std::endl;
std::cout << "*iCont1 == *iCont2 -> " << (*iCont1 == *iCont2 ? "true" : "false") << " || Expecting -> " << "false" << std::endl;
std::cout << "iCont1 == iCont3 -> " << (iCont1 == iCont3 ? "true" : "false") << " || Expecting -> " << "false" << std::endl;
std::cout << "*iCont1 == *iCont3 -> " << (*iCont1 == *iCont3 ? "true" : "false") << " || Expecting -> " << "false" << std::endl;
return 0;
}
答案 0 :(得分:4)
请记住,它们是IContainer指针,但那里没有存储IContainer。您正在取消引用子类,而不是父抽象类。
SimpleContainer cont1(1), cont2(2), cont3(1);
IContainer* iCont1 = &cont1;
IContainer* iCont2 = &cont2;
IContainer* iCont3 = &cont3;
上面你创建了一些SimpleContainers
,你说嘿,我想引用这些作为IContainers,因为我可以有相同的父类的其他类似的对象,我可以将它们组合在一起,因为我的抽象类将处理如何使用这些功能。此过程并未改变SimpleContainer
仍存储在同一位置的事实。你所有的指针都在说那个位置有某种容器。
iCont1 == iCont2
检查两个对象的内存位置是否相同
*iCont1 == *iCont2
使用您定义的==
重载检查相等性。
答案 1 :(得分:2)
你是对的,你不能拥有抽象类IContainer
的实例,但取消引用指针并没有给你一个实例,它会给你一个引用(IContainer&
),完全允许。它是对(未指定的)派生类型的引用。由于它是一个引用,您可以使用点语法或其他运算符来访问接口的方法,它将使用普通的虚拟查找来查找正确的重写方法来调用,就像它是一个指针一样。所以,是的,你正在做的事情是有效的,而且是安全的。
不相关,iCont1 == iCont2
比较两个指针(也称为地址)是否相等,*iCont1 == *iCont2
比较两个值(即对象)是否相等。想想第一个问两个房子是否有相同的街道地址,第二个是两个房子看起来是一样的。两个房子可能看起来一样,但他们仍然有不同的街道地址。但如果两个街道地址相同,你知道只有一个房子涉及。两个比较非常彼此不同。