C++ C++;继承和数组
这里是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()不起作用 还有一个问题,有人能给我举一个简单构造函数类的对象数组的例子吗?出于某种原因,我对此有意见。如果有点复杂的话,我会再
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
不是aB
它将检测错误,并引发异常
多态性
因为虚函数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