2

In the below code SecClass is inheriting 'item' from FirstClass. However when I run 'ClassC' in main both the first item and second item are 210. If I remove the pointer from the inherited class(FirstClass), it runs as it should. I'm still rather shaky with both pointers and inheritance so there's something I'm missing here...

// 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;
}
huitlacoche
  • 173
  • 1
  • 2
  • 15

2 Answers2

4

Your constructor

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

is doing a Very Bad Thing, that is storing the address of a temporary object (the int passed to the constructor).

That int will be destroyed right after returning from the constructor and your item pointer will be pointing to a memory area that has been reused for something else.

Anything can happen when you do this kind of things (including daemons flying out of your nostrils) so don't do that.

6502
  • 112,025
  • 15
  • 165
  • 265
  • Should I dereference first? If I do *item = &thatItem, this causes an error for me. – huitlacoche Sep 03 '13 at 20:04
  • @huitlacoche: you need to allocate the space for `item` as you do in other constructor without parameters and **only then** copy the value. – 6502 Sep 03 '13 at 20:40
  • Okay, I got it. Since I'm still not sure how best to use pointers I figured it'd be best to use them as often as possible. However, if I kept all my class data members on the stack and created pointers to class objects (ie FirstClass *classA = new FirstClass, for example) is this not achieving the same basic idea? – huitlacoche Sep 03 '13 at 21:00
  • If I instead use (int *item = new int;) in FirstClass.h, I get a warning to the tune of [Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default] Any idea what this is about? – huitlacoche Sep 04 '13 at 00:45
  • @huitlacoche: in C++03 initializers for members can be only specified in constructors. If you don't understand the difference between a non-static member and a static member then you really should do yourself a favor by stopping playing with a C++ compiler starting instead reading a good C++ book (eg. one from http://stackoverflow.com/q/388242/320726 ). C++ is ok, but really the wrong language to learn by experimentation for many different reasons no matter how smart you are (actually the smarter you are and the worse it is because logic won't always help). – 6502 Sep 04 '13 at 06:04
0

Here is the modified code that uses the pointers. It works. As you mentioned, it is only to learn about pointers etc.

    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;
}
Testing
  • 76
  • 3
  • thanks, I'll give this a run. I honestly need to read over data allocation in C++ further. The concept still eludes me. Thank for all your help – huitlacoche Sep 27 '13 at 00:32