Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何处理在接受基类数组的函数中将派生类数组作为参数传递?_C++_Arrays_Polymorphism_Pass By Reference_Slice - Fatal编程技术网

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。

A
d
数组永远不会看起来像
b
数组,因为这些类型的大小不同。
D
的大小比A
B
大,因此
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
class
D
std::vector
你能解释为什么要将class D虚拟化吗?另外,我正在寻找一种不使用vector或unique的解决方案,但感谢你的回答
B
a
virtual
析构函数。这就是所谓的运行时多态性。“我正在寻找一种不使用矢量或唯一\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;
}