抽象类和丢失信息
Abstract Classes and Losing Information
我有一个关于从抽象类创建类以及如何剪切数据的问题。
假设我们有一个名为 Animal 的抽象类,以及实现该类的名为 Cat and Dog 的类。这两个类都实现了来自 Animal 的一个名为 update() 的方法;但是,在他们的更新方法中,他们访问私有方法和/或变量,这些方法和/或变量是独占的,而不是 Animal 类。我知道如果我们以这种方式声明类......
Animal* dog = new Dog();
Animal* cat = new Cat();
我们只能访问只有 Animal 类专门具有的方法或变量;但是,如果我在每个类上调用 update() 方法,并且此更新方法调用 Cat and Dog 中的独占成员怎么办。这是合法的,还是因为我将它们创建为动物而被截断?
该语言不会强制您仅使用对方法"update()"的多态访问。
例:
class Animal {
public:
virtual void update() { std::cout << "Animal::update() " << std::endl; }
virtual ~Animal(){}
};
class Cat : public Animal {
public:
virtual ~Cat(){}
virtual void update() { std::cout << "Cat::update() " << std::endl; }
};
class Dog : public Animal {
public:
virtual ~Dog(){}
virtual void update() { std::cout << "Dog::update() " << std::endl; }
};
int t395(void)
{
Animal* dog = new Dog();
Animal* cat = new Cat();
dog->update();
cat->update();
dog->Animal::update();
return (0);
}
// OUTPUT:
// Dog::update()
// Cat::update()
// Animal::update()
。我们只能访问只有动物的方法或变量 类具体有;
我同意。。。 狗是一种动物,没有方法Bark,因此无法调用dog->bark()。 但是,你可以向这三个方法添加一个方法"virtual void talk()",也许虚拟void Dog::talk()会简单地调用它的本地Dog::bark()方法,而Cat::talk()会简单地调用它的本地Cat::meow()方法。
但是,如果我在每个类上调用 update() 方法怎么办, 而这个更新方法调用独占的 《猫与狗》中的成员。这是合法的,还是这些数据是合法的 被截断是因为我将它们创建为动物?
法律 - 是的。 数据不会被截断(在动物、狗或猫中)
a) 多态狗是动物,具有动物的所有方法和数据属性。
b)它还具有狗的所有方法和属性。
实现是特定于编译器的,但一个典型的 impl. 是这两个结构(有一些需要编译器注意的复杂性)只是在内存中连接起来。 哪个是第一个并不重要 - 这是一个实现问题。
cat 和 dog 实例都可以访问自己的数据和方法属性,无论这些方法是否未映射到多态表中。
此外,cat 和 dog 实例都可以访问父 Animal 实例中公共或受保护(但不是私有)的部分。
不确定我是否完全理解您的问题,但是您的 update() 描述了一个虚函数调用。
我怀疑你在理解继承和多态性是如何实现的方面遇到了问题,我知道我做到了。请考虑以下事项:
class base
{
private:
int mylocalInt; //inaccessible to anyone but the base.
protected:
int sharedInt = 5;//accessible by base, and any subtype.
public:
base()
{
cout<<"creating base object"<<endl;
}
virtual ~base()
{
cout<<"Now destroying base object"<<endl;
}
void virtual callMe()//will be overridden, only called if you directly instantiate a base object.
{
cout<<"I am a base"<<endl;
}
};
class subtypeA : public base
{
private:
int Aint;
public:
subtypeA()
{
cout<<"creating subtype"<<endl;
}
~subtypeA()
{
cout<<"destroying subtype"<<endl;
}
void callMe()
{
cout<<"I am a subtypeA"<<endl;
}
int getAint()//this is a local, IE static function, a base ptr cannot access it.
{
return Aint;
}
int getSharedInt()//notice how sharedInt, located in the base object, is still accessible from within the subtype.
{
return sharedInt;
}
};
int main(int argc, char* argv[] )
{
base* ptr = new subtypeA;
ptr->callMe();//works fine, will check which subtype, if any, ptr points to, and call the appropriate callMe(). This is because
//callMe() is virtual in base.
//ptr->sharedInt//illegal, main is not part of base or a subtype of base.
subtypeA* Aptr = (subtypeA*)ptr;//since all pointers are the same size, they can be cast to one another, is dangerous however
cout<<Aptr->getSharedInt()<<endl;//works, getSharedInt is NOT virtual, but a normal static member of subtypeA, so in order to use it, the pointer
//needs to be of type subtypeA. the sharedInt however is protected, so subtypeA can access it due to the fact that it is related to it's owner, base.
}
现在拿起它,并尝试它,添加一个子类型B,然后将子类型添加到该子类型,例如IE子类型AA和BB。
请注意,每个单独的类仍然是它自己的对象,不同于与其相关的任何对象。因此,如果变量是私有的,则不能像普通对象一样从外部直接访问它。
再说一遍:多态性没有什么特别之处,它只是一个很好的抽象,隐藏了"丑陋"的类型检查等等,以促进虚拟调用。
我完全忘记了你的另一个问题。不,在这种情况下,您永远不必担心截断。其实我前段时间问了或多或少同样的问题,看看:C++亚型放在容器中时退化
达斯布林肯莱特出色地解释道。
- 无法创建抽象类的实例
- 用pybind11包装C++抽象类时出错
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 抽象类错误,请参阅声明" "是抽象的
- 将自定义函数传递到基抽象类中以延迟执行
- 将包含抽象类和普通类C++包导出到 Python
- C++:处理抽象类中的错误时出现问题
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 在 C++ 中使用另一个头文件中的抽象类
- ATL::CComContainedObject<contained>: C2259 无法实例化抽象类
- C++:从抽象类重写纯虚拟运算符重载
- 如何创建shared_ptr抽象类的容器
- .h 或.cpp文件中的抽象类或两者兼而有之?
- 从抽象类继承以创建另一个抽象类时,我应该重新声明所有虚函数吗?
- E0322:不允许使用抽象类类型 " " 的对象
- 可视抽象类 c++(错误 LNK 2001:未解析的外部符号)
- 信息在类之间丢失
- 提升 - 类没有名为"序列化"的成员(抽象类)?
- 抽象类和丢失信息