C 可以通过使用要求其为某个类别的对象来声明对象

C++, Is is possible to declare an object with using the requiring it to be of a certain class?

本文关键字:对象 声明 可以通过      更新时间:2023-10-16

首先,我是C 的新手,尤其是以OOP方式使用C 。我有一个带有多个子类的课程,我想知道我是否可以模棱两可地声明一个变量以接受对象而不限制可以存储哪些对象。我之所以问,是因为其中一个孩子最终会一次被使用。因此,如果我不能模棱两可声明一个变量,则可以确定正在使用的众多变量中的哪些方法。

的线

obj randomObj = new className;

而不是

className randomObj = new className

您说您是C 的新手,以及用来描述想要的内容的语法表明您对Java或C#(例如Java或c#)的其他语言更熟悉。您显示的语法在这些语言中正常工作:

Foo myFoo = new DerivedFoo;

这起来是因为,在Java和C#myFoo中的幕后实际上是指向Foo的指针,而不是作为能够存储Foo的固定内存区域的名称。在C 中,语法Foo myFoo创建了这样的固定内存区域。即使您尝试通过这样做将一些派生类型放在那里:

DerivedFoo myDerivedFoo;
Foo myFoo = myDerivedFoo;

myFoo仍然只能容纳一个foo对象。在myFoo初始化期间,所有不是FOO的东西都被"切成",因为它不适合该固定内存区域。

因此,在C 中,您必须通过使用C 的指针语法明确地做Java和C#在幕后做的事情:

    Foo *myFoo = new DerivedFoo;

现在myFoo是指向FOO的指针,该指针可以指代任何Foo对象,包括衍生品的FOO部分,而无需任何切片或任何发生的任何东西。new DerivedFoo创建一个内存区域,其中可能存在衍生品,然后将myFoo设置为指向创建DerivedFooFoo部分。

由于所有类均来自公共基类,因此您可以将变量声明为基类类型,但仍然能够为其分配任何派生类,例如:

class BaseClass
{
...
};
class DerivedClass : public BaseClass
{
...
};
BaseClass *randomObj = new DerivedClass;

容器只能由同一类型的对象组成。如果您想要一个异质收藏,则需要将"句柄"类型粘贴到容器中,并间接访问对象。标准手柄类型为A Pointer ,标准结构为std::vector<std::unique_ptr<Base>>,如下:

#include <memory>
#include <utility>
#include <vector>
template <typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args &&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); // or "::new"
}
struct Base
{
     virtual ~Base() { }
};
struct Derived1 : Base { /* ... */ };
struct Derived2 : Base { /* ... */ };
struct Derived3 : Base { /* ... */ };
std::vector<std::unique_ptr<Base>> v;

用法:

v.push_back(make_unique<Derived1>(true, 'a'));
v.push_back(make_unique<Derived2>(11, 22, 33));
v.push_back(make_unique<Derived3>("hello", "world"));