C++ 如何处理在接受基类数组的函数中将派生类数组作为参数传递?
我有以下两个类的示例代码:C++ 如何处理在接受基类数组的函数中将派生类数组作为参数传递?,c++,arrays,polymorphism,pass-by-reference,slice,C++,Arrays,Polymorphism,Pass By Reference,Slice,我有以下两个类的示例代码: class B { public: int b; }; class D : public B { public: int d; }; 我有一个函数,它接受B作为数组,并对B成员求和: int sum(B a[], int count){ int sum = 0; for(int i = 0; i < count; i++) { sum += a[i].b; } return sum; }
class B {
public:
int b;
};
class D : public B {
public:
int d;
};
我有一个函数,它接受B作为数组,并对B成员求和:
int sum(B a[], int count){
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i].b;
}
return sum;
}
以通过引用传递,但这会导致编译错误,因为无法使用引用数组
我的问题是这样做的最佳方式是什么
目前我的解决方案是将我的数组声明为:
B* a = new D[3];
但不完全清楚为什么它不能很好地与以前的实现配合使用。您提出的解决方案实际上是正确的,但是您可能希望使用virtual关键字将B抽象化。 另一种选择是重新定义sum函数,并使其接受已定义的对象 解释原始实现无法工作的直观方法如下: 在sum正文中,我们有以下代码行:
sum+=a[i].b代码>其中a是指向类型B的对象的指针
这意味着为了获得索引i
处的元素,我们需要添加
i*sizeof(B)
到基址a。然而,这个地址现在是错误的,我们需要的是地址i*sizeof(D)
通过将指针类型声明为B,可以解决此问题
顺便说一下,您可能还希望使b变量受保护,d变量为私有,然后提供getter。Ad
数组永远不会看起来像b
数组,因为这些类型的大小不同。D
的大小比AB
大,因此D
数组中的连续元素将比B
数组中的连续元素间隔更远(因为每个元素占用更多空间)
如果希望子类型多态性工作,则需要使用指针(或引用),而不是对象类型本身。不能有引用数组,因此必须使用指针数组
类似这样的方法会奏效:
int sum(B *a[], int count) {
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i]->b;
}
return sum;
}
int main() {
D *a[3];
for (int i = 0; i < 3; i++) {
a[i] = new D;
a[i]->b = i+1;
}
cout << "Sum is " << sum((B **)a, 3) << endl;
for (int i = 0; i < 3; i++) {
delete a[i];
}
return 0;
}
也可以使用模板:
template <class T>
int sum(T *a[], int count) {
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i]->b;
}
return sum;
}
int main() {
D *a[3];
for (int i = 0; i < 3; i++) {
a[i] = new D;
a[i]->b = i+1;
}
cout << "Sum is " << sum(a, 3) << endl;
for (int i = 0; i < 3; i++) {
delete a[i];
}
return 0;
}
模板
整数和(T*a[],整数计数){
整数和=0;
for(int i=0;ib;
}
回报金额;
}
int main(){
D*a[3];
对于(int i=0;i<3;i++){
a[i]=新的D;
a[i]>b=i+1;
}
不能使用virtual
classD
和std::vector
你能解释为什么要将class D虚拟化吗?另外,我正在寻找一种不使用vector或unique的解决方案,但感谢你的回答B
avirtual
析构函数。这就是所谓的运行时多态性。“我正在寻找一种不使用矢量或唯一\u ptr的解决方案”。您可以使用原始数组和原始指针,但不建议这样做。您不能将派生类对象数组传递给接受基类对象数组的函数。这是不可能的。sum((B**)a,3)
这只是未定义的行为。
int sum(B *a[], int count) {
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i]->b;
}
return sum;
}
int main() {
D *a[3];
for (int i = 0; i < 3; i++) {
a[i] = new D;
a[i]->b = i+1;
}
cout << "Sum is " << sum((B **)a, 3) << endl;
for (int i = 0; i < 3; i++) {
delete a[i];
}
return 0;
}
int sum(B *a[], int count) {
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i]->b;
}
return sum;
}
int main() {
B *a[3];
for (int i = 0; i < 3; i++) {
a[i] = new D;
a[i]->b = i+1;
}
cout << "Sum is " << sum(a, 3) << endl;
for (int i = 0; i < 3; i++) {
delete a[i];
}
return 0;
}
template <class T>
int sum(T *a[], int count) {
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i]->b;
}
return sum;
}
int main() {
D *a[3];
for (int i = 0; i < 3; i++) {
a[i] = new D;
a[i]->b = i+1;
}
cout << "Sum is " << sum(a, 3) << endl;
for (int i = 0; i < 3; i++) {
delete a[i];
}
return 0;
}
template <class T>
int sum(T a[], int count) {
int sum = 0;
for(int i = 0; i < count; i++) {
sum += a[i].b;
}
return sum;
}
int main() {
D a[3];
for (int i = 0; i < 3; i++) {
a[i].b = i+1;
}
cout << "Sum is " << sum(a, 3) << endl;
return 0;
}