C++ C++;继承和数组

C++ C++;继承和数组,c++,arrays,inheritance,C++,Arrays,Inheritance,这里是c++新手 我是在检查C++中的类是如何工作的,我写了这个代码: class A{ ... } class B: public A{ ... } int main(void){ A array[10]; } < C++中的继承与java中的继承是否相同? 我可以在数组中添加B类型的对象吗?如果可以,我将如何添加? 只需执行array[0]=new B()不起作用 还有一个问题,有人能给我举一个简单构造函数类的对象数组的例子吗?出于某种原因,我对此有意见。如果有点复杂的话,我会再

这里是c++新手

<>我是在检查C++中的类是如何工作的,我写了这个代码:

class A{
   ...
}
class B: public A{
...
}
int main(void){
  A array[10];
}
< C++中的继承与java中的继承是否相同? 我可以在数组中添加B类型的对象吗?如果可以,我将如何添加? 只需执行
array[0]=new B()不起作用


还有一个问题,有人能给我举一个简单构造函数类的对象数组的例子吗?出于某种原因,我对此有意见。如果有点复杂的话,我会再发一个问题。在Java中,类类型的变量始终是对对象的引用。即

A a = new A();
A a2 = a; // now a and a2 represent the same object
a.x = 12; // now print(a2.x) will also output 12
newa()
将在堆上创建实际对象(可以动态分配的内存区域),并返回该对象的内存地址
a
a2
实际上(内部)只包含该地址

与包含实际值的整型变量不同,因此:

int a = 1;
int a2 = a;
a = 3;
// now a2 will still be 1
在C++中,P>对象以堆栈的形式放置在堆栈上(除非使用引用或指针)。因此:

执行
a=b
仅将
b
中的值从其超类复制到
a

工具书类 现在
a_ref
是对
a
与Java不同,不能使引用指向另一个对象。 相反,执行
a_ref=a2
的效果与
a=a2

a.x = 2
std::cout << a_ref.x << std::endl; // now outputs 2
这(静态向上投射)不建议使用,仅当您确定
a_ref2
指向
B
对象时才有效。否则将填充故障/崩溃

如果
A
是多态的(见下文),则可以改用
dynamic\u cast(A\u ref2)
(仍不推荐)。如果
a_ref2
不是a
B
它将检测错误,并引发异常

多态性 因为虚函数A和B是多态类。由于
A\u ref
的类型为
A&
,因此在编译时不知道这将调用
A::get\u v
还是
B::get\u v
。相反,要调用的函数是在运行时决定的,这取决于
a_ref
指向的对象。在Java中,所有函数都是这样的

a_ref.get(); // returns 1.
因为
get()
不是多态的,它调用
A
get()
函数,因为
A\u ref
属于
A&
类型

a_ref.get_a(); // returns 3, by inheritance
指针 指针类似于引用,但级别较低。访问引用的方式与实际对象相同(
a_ref.x
b.x
)。指针变量是地址。与参照不同,初始指定后可以使它们指向另一个对象:

B b; // same classes A and B as before
A* a_ptr = &b; // a is now a pointer to b.
// The type A* means "pointer to B". &b means "address of b".

// Polymorphism works the same:
a_ptr->get_v(); // returns 2
a_ptr->get(); // returns 1.
a_ptr->get_a(); // returns 3.
动态内存分配还返回指针:

A* a_ptr = new B(); // a_ptr is now a pointer to a B allocated on the heap
...
delete a_ptr; // must be done to deallocate the B, otherwise there will be a memory leak.
因为a_ptr的类型是
a*
(而不是
B*
),多态类的析构函数应该是虚拟的:

class A {
public:
    ...
    virtual ~A() { .... }
};
class B : public A {
public:
    ...
    ~B() override { .... }
};
否则只有
A::~A
会被调用

因此,在您的情况下,您可以:

A* array[10];
array[0] = new B();

array[0]->get_v();
delete array[0];
但是数组中所有尚未初始化的指针都将无效。也就是说,
array[1]->get_v()
delete array[1]
将是一个错误

array
将是指向
A
类型的对象的指针数组,或
A
的子类

您还可以动态分配一个数组,如下所示:

A* array = new[10] A; // array is now a pointer to an array
array[0].x = 1;
delete[] array; // Deallocates as many items as where allocated
但这与在堆栈上按[10]
执行
A操作相同。这些将是
A
对象,执行
array[0]=b
只需从
b
复制
b.x

独特的 一个好的解决方案可能是使用STL中的
std::unique_ptr
。它是指针的包装,因此没有两个
unique\u ptr
可以指向同一项。(因为禁止复制
唯一\u ptr
等):

它将始终调用默认构造函数(不带参数)。没有办法向它传递参数

std::array
可以进行复制初始化(即构造函数采用单个值:)

A类{
公众:
int x;
A(int-nx):x(nx){}
};
数组ar={1,2,3};
//或
数组ar2={a,a2};//复制

您可以使用
A*数组[10]
然后写入
数组[0]=new B()。只能将派生类的引用和指针强制转换为基类。只需执行
array[0]=new B()不工作,因为无法将
A*
分配给
A
。Java使用指针(称为引用)。如果你在C++中使用指针,它的工作方式也大致相同。@ WOWOBOBB谢谢,我刚刚尝试过,我确实可以把它存储在一个数组中,即使我有一个对象cJava,也可以引用引用不完全像C++指针或者C++引用。我认为最好是分别学习每一种方法最简单、最灵活的方法是
vector
可靠的答案,尽管有点长
B b; // same classes A and B as before
A* a_ptr = &b; // a is now a pointer to b.
// The type A* means "pointer to B". &b means "address of b".

// Polymorphism works the same:
a_ptr->get_v(); // returns 2
a_ptr->get(); // returns 1.
a_ptr->get_a(); // returns 3.
A* a_ptr = new B(); // a_ptr is now a pointer to a B allocated on the heap
...
delete a_ptr; // must be done to deallocate the B, otherwise there will be a memory leak.
class A {
public:
    ...
    virtual ~A() { .... }
};
class B : public A {
public:
    ...
    ~B() override { .... }
};
A* array[10];
array[0] = new B();

array[0]->get_v();
delete array[0];
A* array = new[10] A; // array is now a pointer to an array
array[0].x = 1;
delete[] array; // Deallocates as many items as where allocated
#include <memory>
// needed for std::unique_ptr

std::unique_ptr<A> array[10];
array[0].reset( new B() ); // needed to assign a value to it
array[0]->get_v();
A array[10];
class A {
public:
    int x;
    A(int nx) : x(nx) {}
};

std::array<A, 3> ar = { 1, 2, 3 };
// or
std::array<A, 2> ar2 = { a, a2 }; // makes copies