tags:

views:

317

answers:

2

Thanks to all that responded to my previous thread. There is still a problem with this simple program that I would like to solve. I am trying to import one class into another as a member object. The output of this program is confusing, though. As a test of the code, I output the scalar contained within the first class object. This works. Then I output the scalar the is contained in the object contained as a member of the second class, and this outputs zero. I assume that something is wrong. Could someone shed some light on this problem? Thanks!

#include <iostream>
using namespace std;

typedef double* doublevec;

// This first class contains a vector and a scalar representing the size of the vector.
typedef class Structure1
{
 int N;
 doublevec vec;
public: 
 // Constructor and copy constructor.
 Structure1(int Nin);
 Structure1(const Structure1& structurein);
 // Accessor functions:
 int get_N() { return N; }
 doublevec get_vec() { return vec; }
 // Destructor:
 ~Structure1() { delete []vec; }
} Structure1;

Structure1::Structure1(int Nin)
{
 N = Nin;
 vec = new double [N];
 for (int i = 0; i < N; i++)
  {
   vec[i] = i;
  };
}

Structure1::Structure1(const Structure1& structurein)
{
 vec = new double[structurein.N];
 for(int i = 0; i < structurein.N; i++)
 {
  vec[i] = structurein.vec[i];
 };
}

// This class just contains the first structure.
typedef class Structure2
 {
  Structure1 structure;
 public:  
  // Constructor:
  Structure2(const Structure1& structurein) : structure(structurein) {}
  // Accessor Function:
  Structure1 get_structure() { return structure; }
  // Destructor:
  ~Structure2() {}
 } Structure2;

int main (int argc, char * const argv[])
{
 const int N = 100;
 Structure1 structure1(N);
 Structure2 structure2(structure1);

 cout << structure1.get_N() << endl;
 cout << structure2.get_structure().get_N();

 return 0;
}
+1  A: 

Looks like you don't set N in Structure1's copy constructor. You need:

Structure1::Structure1(const Structure1& structurein){
 N = structurein.N;
 vec = new double[structurein.N];
 for(int i = 0; i < structurein.N; i++) {
  vec[i] = structurein.vec[i];
 }
}

(Also, you don't need a semicolon after a for-loop. But that's another matter.)

Edit: This was actually mentioned in an answer to your other question. ;)

Michael Myers
Funny thing is that I don't even know C++ all that well; but I do know how to debug.
Michael Myers
+1  A: 

This has nothing to do with the question, that has been properly answered by mmyers (and already accepted), but since it seems that you are learning, just a couple of advices:

You do not need typedefs for structs or classes, the typename will automatically be available in the namespace. [*]

Make 1 argument constructors explicit and prefer initialization lists to code in the constructor block. Marking explicit will avoid implicit casts from the argument type to the class type.

Constness is important: Mark non-mutating methods as const so that the compiler knows.

Prefer libraries over hand made equivalent solutions. Know the STL (std::vector is probably quite similar to what you are working on, now I understand this is probably for learning)

class Structure1 // typedef removed
{
   int N;
   double *vec;
public:
   explicit Structure1( int Nin );        // explicit to disable implicit conversions from int to Structure1
   Structure1( const Structure1 & stin );
   int get_N() const { return N; }        // marked as const: it won't change the object
   double* get_vector() { return vec; }   // not const: user can change the contents of the vector!
                                          // if you don't want the user to change it return a const double*
};

Structure1::Structure1( int Nin ) 
   : N( Nin ), vec( new double[Nin] )
{
   for ( int i = 0; i < N; ++i ) vec[i] = i;
}
Structure1::Structure1( const Structure1 & other )
   : N( other.N ), vec( new double[other.N] )
{
   for ( int i = 0; i < N; ++i ) vec[i] = other.vec[i];
}

[*] There is a subtle difference, but it won't show up in 99.99% of the code and most C++ programmers don't even know. Most people are used to not typedef-ing classes or structs in C++.

David Rodríguez - dribeas