【问题标题】:Looping thru member array gives wrong values循环通过成员数组给出错误的值
【发布时间】:2016-06-08 14:34:57
【问题描述】:

我设置了两个类,DogAnotherDogDog 并不是AnotherDog 的基类。

AnotherDog 中,我有一个Dog 对象。在该Dog 对象中是一个成员数组。当 AnotherDog 对象调用其 Dog 成员,然后通过其成员数组进行成员循环时,我得到错误的结果。

#include <iostream>

class Dog
{
private:
    int m_NumberOfBarks;
    int m_Decibels[];
public:
    Dog();
    ~Dog();

    void setBarkDecibels(int decibel1, int decibel2);
    void loopDecibels();
};

Dog::Dog() : m_NumberOfBarks(2){}
Dog::~Dog(){}

void Dog::setBarkDecibels(int decibel1, int decibel2){
    m_Decibels[0]=  decibel1;
    m_Decibels[1]=  decibel2;
}

void Dog::loopDecibels(){
    for(int i=0; i<m_NumberOfBarks; ++i){
        std::cout << i << ' ' << m_Decibels[i] << std::endl;
    }
}


class AnotherDog
{
private:
    Dog m_Dog;
public:
    AnotherDog();
    ~AnotherDog();

    Dog getDog();
};

AnotherDog::AnotherDog(){
    m_Dog.setBarkDecibels(10, 100);
}
AnotherDog::~AnotherDog(){}

Dog AnotherDog::getDog(){
    return m_Dog;
}


int main(){
    AnotherDog goodDog;
    goodDog.getDog().loopDecibels();
    return 0;
}

我希望 void Dog::loopDecibels() 打印 10100 以及索引。

相反,我得到了这个:

0 0
1 4196480

我做错了什么?

如何达到我想要的结果?

【问题讨论】:

  • int m_Decibels[]; 无效。您需要指定数组的大小(或者更好的是,使用std::vector)。
  • 在 int[] 中使用 std::vector 代替
  • @crashmstr,它有点有效。有一个古老的神秘规则允许以这种方式定义结构的最后一个成员 - 然后它可以用作指向结构之外的内存的指针 - 一些编译器仍然允许它。
  • 不相关:为什么不创建 1 个狗类,创建 2 只不同的狗,或者给狗一个相互交互的方法,或者让拥有两只狗的对象以某种方式协商它们之间的交互?

标签: c++ arrays class oop member


【解决方案1】:

您的程序表现出未定义的行为。

 int m_Decibels[];

声明一个指向 int 的 指针,并且不为要指向的指针分配任何内存。指针在类构造函数中保持未初始化(因为您没有初始化它)。以后你做的时候

m_Decibels[0]=  decibel1;
m_Decibels[1]=  decibel2;

您正在取消引用这个指针,这是一个禁忌。要解决此问题,您可以使用固定大小的数组:

int m_Decibels[2];

硬币的另一面是,您正在从您的 getDog 按值返回一个 Dog 实例。当您在此特定实例上设置分贝时,它对类的原始 dog 成员没有影响。要解决此问题,您可能希望通过引用返回对象,如下所示:

   Dog& getDog(); // and corresponding change in the definition

【讨论】:

  • 我已经按照@crashmstr 的建议为数组添加了一个大小。您能告诉我“当您在此特定实例上设置分贝时,它对班级的原始狗成员没有影响”是什么意思?你是在说m_dog吗?
  • @Username,当您按值返回 dog 时,您将返回一个副本。对副本的修改不会影响原件。
  • 那么当被'getDog()'调用时,如果我想修改'm_dog',我应该按地址返回? '返回&m_dog'?
  • @Username,最好通过引用返回。让它更清晰。
  • 好的,如果您将其添加到您的答案中,并建议为数组分配大小,我可以将您的答案标记为正确的。
猜你喜欢
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多