2013-09-03 3 views
2

В следующем коде SecClass наследует «элемент» от FirstClass. Однако, когда я запускаю «ClassC», в основном и первый элемент, и второй элемент - 210. Если я удалю указатель из унаследованного класса (FirstClass), он будет работать как следует. Я все еще довольно шатким с обоих указателей и наследование, так что есть что-то я здесь не хватает ...проблемы с унаследованным классом

// declaration of FirstClass 
// FirstClass.h 

#include <iostream> 

#ifndef FIRSTCLASS_H 
#define FIRSTCLASS_H 

using namespace std; 

class FirstClass 
{ 
private: 
    int *item; 

public: 
    FirstClass(); 
    FirstClass(int thatItem); 
    ~FirstClass(); 

    int getItem(); 
    void setItem(int thatItem); 

}; 

#endif 


// the implementation of FirstClass.h 
// FirstClass.cpp 

#include "FirstClass.h" 

using namespace std; 

FirstClass::FirstClass() 
{ 

int *setInitial = new int; 
*setInitial = 5; 
item = setInitial; 
} 

FirstClass::FirstClass(int thatItem) 
{ 
item = &thatItem; 
} 

FirstClass::~FirstClass(){} 

int FirstClass::getItem() 
{ 
    return *item; 
} 

void FirstClass::setItem(int thatItem) 
{ 
    item = &thatItem; 
} 


// declaration of SecClass 
// SecClass.h 

#ifndef SECCLASS_H 
#define SECCLASS_H 

#include "FirstClass.h" 

using namespace std; 

class SecClass : public FirstClass 
{ 
private: 
    int *secItem; 

public: 
    SecClass(); 
    SecClass(int newItem, int thatItem); 
    ~SecClass(); 

    int getSecItem(); 
    void setSecItem(int newItem); 

}; 

#endif 


// the implementation of SecClass.h 
// SecClass.cpp 

#include "SecClass.h" 

using namespace std; 

SecClass::SecClass() 
{ 

int *setSecInitial = new int; 
*setSecInitial = 16; 
secItem = setSecInitial; 
} 

SecClass::SecClass(int newItem, int thatItem) : FirstClass(thatItem) 
{ 
    secItem = &newItem; 
} 

SecClass::~SecClass(){} 

int SecClass::getSecItem() 
{ 
    return *secItem; 
} 

void SecClass::setSecItem(int newItem) 
{ 
    secItem = &newItem; 
} 


// main program 
#include <iostream> 
#include "FirstClass.h" 
#include "SecClass.h" 

using namespace std; 

int main() 
{ 

FirstClass classA; 
cout << "classA item: " << classA.getItem() << endl << endl; 

FirstClass classZ(86); 
cout << "classZ item: " << classZ.getItem() << endl << endl; 

SecClass classB; 
cout << "classB first item: " << classB.getItem() << endl; 
cout << "classB second item: " << classB.getSecItem() << endl << endl; 

SecClass classC(72, 210); 
cout << "classC first item: " << classC.getItem() << endl; 
cout << "classC second item: " << classC.getSecItem() << endl; 


return 0; 
} 

ответ

4

Ваш конструктор

void FirstClass::setItem(int thatItem) 
{ 
    item = &thatItem; 
} 

делает очень плохо, что хранит адрес временного объекта (int, переданного конструктору).

То, что int будет уничтожено сразу после возвращения из конструктора, и указатель item будет указывать на область памяти, которая была повторно использована для чего-то еще.

Все может случиться, когда вы делаете такие вещи (включая daemons flying out of your nostrils), поэтому не делайте этого.

+0

Должен ли я сначала разыменоваться? Если я делаю * item = & thatItem, это вызывает ошибку для меня. – huitlacoche

+0

@huitlacoche: вам нужно выделить пространство для 'item', как и в другом конструкторе без параметров, и ** только тогда ** скопировать значение. – 6502

+0

Хорошо, я понял. Поскольку я все еще не уверен, как лучше использовать указатели, я решил, что лучше использовать их как можно чаще. Однако, если бы я сохранил все члены класса в стеке и создал указатели на объекты класса (например, FirstClass * classA = new FirstClass, например), это не достижение той же базовой идеи? – huitlacoche

0

Вот модифицированный код, который использует указатели. Оно работает. Как вы упомянули, это только узнать о указателях и т. Д.

class FirstClass 
{ 
private: 
    int *item; 

public: 
    FirstClass(); 
    FirstClass(int *thatItem); 
    ~FirstClass(); 

    int getItem(); 
}; 

FirstClass::FirstClass() 
{ 
item = new int(5); 
} 

FirstClass::FirstClass(int *thatItem) 
{ 
item = thatItem; 
} 

FirstClass::~FirstClass(){} 

int FirstClass::getItem() 
{ 
    return *item; 
} 

class SecClass : public FirstClass 
{ 
    private: 
    int *secItem; 

    public: 
    SecClass(); 
    SecClass(int *newItem, int *thatItem); 
    ~SecClass(); 

    int getSecItem(); 
}; 

SecClass::SecClass() 
{ 
secItem = new int(16); 
} 

SecClass::SecClass(int *newItem, int *thatItem) : FirstClass(thatItem) 
{ 
    secItem = newItem; 
} 

SecClass::~SecClass(){} 

int SecClass::getSecItem() 
{ 
    return *secItem; 
} 

int main() 
{ 

FirstClass classA; 
cout << "classA item: " << classA.getItem() << endl << endl; 

int *i = new int(86); 
FirstClass classZ(i); 
cout << "classZ item: " << classZ.getItem() << endl << endl; 

SecClass classB; 
cout << "classB first item: " << classB.getItem() << endl; 
cout << "classB second item: " << classB.getSecItem() << endl << endl; 

int *j = new int(72); 
int *k = new int(210); 
SecClass classC(j,k); 
cout << "classC first item: " << classC.getItem() << endl; 
cout << "classC second item: " << classC.getSecItem() << endl; 


return 0; 
} 
+0

спасибо, я дам этому пробег. Я, честно говоря, должен продолжить чтение данных на C++. Концепция все еще ускользает от меня. Спасибо за вашу помощь – huitlacoche