Solved

msvc++/appwizard problem

Posted on 1998-09-13
8
245 Views
Last Modified: 2010-04-02
I have a class I wrote, and it uses the

#ifndef __class_h
#define __class_h

class definition....

#endif

format.  the problem is when I try to include it in an appwizard program I get 46 errors that list all of the functions in my class and says that they are all multiply defined symbols that have already been defined in MyApp.obj.  it says this for MainFrame.obj, MyAppView.obj and MyAppDoc.obj.  now I would think that I am including it in the wrong place or doing something else wrong but when I include another of my user defined classes in that same place (right after #include "resource.h" in MyApp.h) it compiles just fine!  so it must be something to do with the class but I have looked over and over it and can see nothing that makes it any different from any of my other classes.  I have even made a non appwizard program and included it and it works just fine!!!  can somebody please shed some light as to what is going on?  thank you.
0
Comment
Question by:Booth882
  • 5
  • 3
8 Comments
 
LVL 1

Author Comment

by:Booth882
ID: 1172593
here is the code for the class:

#ifndef __creature_h
#define __creature_h

#include <array.h>

enum CreatureDirection
{
      Still,
      Up,
      Down,
      Left,
      Right,
      Towards,
      Away
};

class creature
{
private:
      int Size;
      int CurrentSegment;
      int LastSegment;
      array<int> XValues;
      array<int> YValues;
      array<int> ZValues;
      int XAdjust;
      int YAdjust;
      int ZAdjust;
      int XLimit;
      int YLimit;
      int ZLimit;
public:
      creature(int InitialSize, int InitialXLimit, int InitialYLimit, int InitialZLimit);
      ~creature();

      int GetSize(){return Size;};
      void GetHead(int & XCast, int & YCast);
      void GetHead(int & XCast, int & YCast, int & ZCast);
      void GetTail(int & XCast, int & YCast);
      void GetTail(int & XCast, int & YCast, int & ZCast);
      void GetSegment(int Which, int & XCast, int & YCast);
      void GetSegment(int Which, int & XCast, int & YCast, int & ZCast);
      void SetSegment(int Which, int XPosition, int YPosition);
      void SetSegment(int Which, int XPosition, int YPosition, int ZPosition);
      void AddSegment(int Number);
      void SetXAdjust(int NewXAdjust){XAdjust = NewXAdjust;};
      void SetYAdjust(int NewYAdjust){YAdjust = NewYAdjust;};
      void SetZAdjust(int NewZAdjust){ZAdjust = NewZAdjust;};
      void SetDirection(int Direction);
      void ValueAdjust(array<int> & Values, int Adjust, int Limit);
      void MoveCreature();
};

creature::creature(int InitialSize, int InitialXLimit, int InitialYLimit, int InitialZLimit)
{
      Size = InitialSize;
      XLimit = InitialXLimit;
      YLimit = InitialYLimit;
      ZLimit = InitialZLimit;
      
      XValues.MakeSize(Size);
      YValues.MakeSize(Size);
      ZValues.MakeSize(Size);
      
      CurrentSegment = 0;
      LastSegment = 1;
      SetSegment(0, XLimit / 2, YLimit / 2, ZLimit / 2);
      
      int TempX = 0;
      
      for(int b = 1; b < Size; b++)
      {
            TempX = XLimit / 2 - (Size - b);
            if(TempX > XLimit)
                  TempX -= (XLimit + 1);
            if(TempX < 0)
                  TempX += (XLimit + 1);
            SetSegment(b, TempX, YLimit / 2, ZLimit / 2);
      }

      XAdjust = 1;
      YAdjust = 0;
      ZAdjust = 0;
}

creature::~creature()
{
}

void creature::GetHead(int & XCast, int & YCast)
{
      XCast = XValues[CurrentSegment];
      YCast = YValues[CurrentSegment];
}

void creature::GetHead(int & XCast, int & YCast, int & ZCast)
{
      XCast = XValues[CurrentSegment];
      YCast = YValues[CurrentSegment];
      ZCast = ZValues[CurrentSegment];
}

void creature::GetTail(int & XCast, int & YCast)
{
      XCast = XValues[LastSegment];
      YCast = YValues[LastSegment];
}

void creature::GetTail(int & XCast, int & YCast, int & ZCast)
{
      XCast = XValues[LastSegment];
      YCast = YValues[LastSegment];
      ZCast = ZValues[LastSegment];
}

void creature::GetSegment(int Which, int & XCast, int & YCast)
{
      XCast = XValues[Which];
      YCast = YValues[Which];
}

void creature::GetSegment(int Which, int & XCast, int & YCast, int & ZCast)
{
      XCast = XValues[Which];
      YCast = YValues[Which];
      ZCast = ZValues[Which];
}

void creature::SetSegment(int Which, int XPosition, int YPosition)
{
      XValues[Which] = XPosition;
      YValues[Which] = YPosition;
}

void creature::SetSegment(int Which, int XPosition, int YPosition, int ZPosition)
{
      XValues[Which] = XPosition;
      YValues[Which] = YPosition;
      ZValues[Which] = ZPosition;
}

void creature::AddSegment(int Number)
{
      int Void = -1;
      
      for(int n = 0; n < Number; n++)
      {
            XValues.AddToArray(Void);
            YValues.AddToArray(Void);
            ZValues.AddToArray(Void);

            Size++;
      }

      if(LastSegment == 0)
            LastSegment = CurrentSegment + 1;
}

void creature::SetDirection(int Direction)
{
      switch(Direction)
      {
      case Up:
            XAdjust = 0;
            YAdjust = 1;
            ZAdjust = 0;
            break;
      case Down:
            XAdjust = 0;
            YAdjust = -1;
            ZAdjust = 0;
            break;
      case Left:
            XAdjust = -1;
            YAdjust = 0;
            ZAdjust = 0;
            break;
      case Right:
            XAdjust = 1;
            YAdjust = 0;
            ZAdjust = 0;
            break;
      case Towards:
            XAdjust = 0;
            YAdjust = 0;
            ZAdjust = -1;
            break;
      case Away:
            XAdjust = 0;
            YAdjust = 0;
            ZAdjust = 1;
            break;
      }
}

void creature::ValueAdjust(array<int> & Values, int Adjust, int Limit)
{
      Values[LastSegment] = Values[CurrentSegment] + Adjust;
      if(Values[LastSegment] > Limit)
            Values[LastSegment] = 0;
      if(Values[LastSegment] < 0)
            Values[LastSegment] = Limit;
}

void creature::MoveCreature()
{
      ValueAdjust(XValues, XAdjust, XLimit);
      ValueAdjust(YValues, YAdjust, YLimit);
      ValueAdjust(ZValues, ZAdjust, ZLimit);
      
      CurrentSegment += 1;
      if(CurrentSegment >= Size)
            CurrentSegment = 0;
      LastSegment += 1;
      if(LastSegment >= Size)
            LastSegment = 0;
}

#endif



where <array.h> is my own array class.
0
 
LVL 2

Accepted Solution

by:
prasanth earned 100 total points
ID: 1172594
You need to split this up into creature.h and creature.cpp. The class definition should go into creature.h and the function implementations should go into creature.cpp. Then include only creature.h in all your other files or in MyApp.h (which in turn is included in al other files). But add both files to your project.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1172595
but then why do my other user defined classes work?  they are in the same format.
0
 
LVL 2

Expert Comment

by:prasanth
ID: 1172596
I'm not sure but the #ifndef __class_h will only keep out multiple copies of header files from being included in the SAME file. But what is happening right now is that (for example) there is a create::AddSegment in MyApp.cpp, another create::AddSegment in MainFrame.cpp, yet another create::AddSegment in MyAppView, and so on. And it is the linker generating errors about finding more than one implementation for each function when it links together all the obj files.

How many other user defined classes do you have? Is each of those classes in one .h file, both definition and implementation? Can you maybe post another of your classes that works?


0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 1

Author Comment

by:Booth882
ID: 1172597
alright there are no more multiply defined but there is a fatal error at the end of "creature.cpp" that says "unexpected end of file while looking for precompiled header directive."  what's going on now.  oh I inserted the file into the project and included <creature.h> in creature.cpp, but I gathered I was supposed to do that from the way the other .cpps are designed.  

I attempt to use primarily my own classes just because I can adjust them whenever I need to and I gain an intimate knowledge of the objects I'm working with.  and so far yes, all of them have been declaration and implementation in the same .h file and I have had no trouble until now.  I always saw that they divided things into a .h and a .cpp but I thought it was more out of style and had nothing to do with the way it actually worked.  and other classes I have work fine in appwizard!!  it just doesnt make any sense.  I will post another class that works so you can check to see if I am doing anything different in the two, but I havent been able to see it.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1172598
#ifndef __array_h
#define __array_h

#include <stdio.h>
#include <stdarg.h>

template <class T>
class array
{
private:
      T * TheArray;
      int TheLength;
public:
      array();
      array(int InitialLength);
      array(array & CopyArray);
      ~array();

      array & operator=(array & ArrayReference);
      array & operator=(int const TheInt);
      T & operator[](int Offset);
      
      int GetTheLength(){return TheLength;};
      T * GetTheArray(){return TheArray;};
      void GrowTheArray(int AmountOfGrowth);
      void ShrinkTheArray(int AmountOfShrank);
      void MakeSize(int NewSize);
      void AddToArray(T & TReference);
      void AssignArray(int InputCount, ...);
};

template <class T>
array<T>::array()
{
      TheLength = 4;
      TheArray = new T[TheLength];
      for(int hon = 0; hon < TheLength; hon++)
            TheArray[hon] = 0;
}

template <class T>
array<T>::array(int InitialLength)
{
      TheLength = InitialLength;
      TheArray = new T[TheLength];
      for(int hon = 0; hon < TheLength; hon++)
            TheArray[hon] = 0;
}

template <class T>
array<T>::array(array & CopyArray)
{
      TheLength = CopyArray.GetTheLength();
      TheArray = new T[TheLength];
      for(int boj = 0; boj < TheLength; boj++)
            TheArray[boj] = CopyArray[boj];
}

template <class T>
array<T>::~array()
{
      delete [] TheArray;
      TheArray = 0;
}

template <class T>
array<T> & array<T>::operator=(array<T> & ArrayReference)
{
      int TheDifference = (ArrayReference.GetTheLength() - TheLength);
      if(TheDifference > 0)
            GrowTheArray(TheDifference);

      if(TheDifference < 0)
            ShrinkTheArray(0 - TheDifference);
      
      for(int Pount = 0; Pount < TheLength; Pount++)
            TheArray[Pount] = ArrayReference[Pount];
      
      return *this;
}

template <class T>
array<T> & array<T>::operator=(int const TheInt)
{
      if(TheInt == 0)
      {
            for(int j = 0; j < TheLength; j++)
                  TheArray[j] = 0;
      }

      return *this;
}

template <class T>
T & array<T>::operator[](int Offset)
{
      return TheArray[Offset];
}

template <class T>
void array<T>::GrowTheArray(int GrowthAmount)
{
      if(GrowthAmount < 1)
            return;
      
      int TempLength = TheLength + GrowthAmount;
      T * TempT = new T[TempLength];

      for(int i = 0; i < TheLength; i++)
            TempT[i] = TheArray[i];
      for(int u = TheLength; u < TempLength; u++)
            TempT[u] = 0;

      delete [] TheArray;
      TheArray = TempT;
      TheLength = TempLength;
}

template <class T>
void array<T>::ShrinkTheArray(int AmountOfShrank)
{
      int TempLength = TheLength - AmountOfShrank;
      if(TempLength < 1)
            return;
      
      T * TempT = new T[TempLength];

      for(int h = 0; h < TempLength; h++)
            TempT[h] = TheArray[h];

      delete [] TheArray;
      TheArray = TempT;
      TheLength = TempLength;
}

template<class T>
void array<T>::MakeSize(int NewSize)
{
      if(NewSize == TheLength)
            return;
      if(NewSize > TheLength)
      {
            GrowTheArray(NewSize - TheLength);
            return;
      }
      if(NewSize < TheLength)
      {
            ShrinkTheArray(TheLength - NewSize);
            return;
      }
}

template<class T>
void array<T>::AddToArray(T & TReference)
{
      GrowTheArray(1);
      TheArray[TheLength - 1] = TReference;
}

template<class T>
void array<T>::AssignArray(int InputCount, ...)
{
      if(InputCount > TheLength)
            GrowTheArray(InputCount - TheLength);
            
      va_list TheArguments;

      va_start(TheArguments, InputCount);
      for(int pp = 0; pp < InputCount; pp++)
            TheArray[pp] = va_arg(TheArguments, T);
      va_end(TheArguments);
}

typedef array<int> intarray;
typedef array<float> floatarray;

#endif

0
 
LVL 2

Expert Comment

by:prasanth
ID: 1172599
Okay, template classes are different. When you define a function for a template class, you really aren't defining a function and that is why the linker won't think there are multiple copies of a function.

So for template classes you can put everything in a .h file. but for other types of classes you need to have a separate cpp and h files - it is not just a matter of style.

The error about the precompiled header directive is because you need to include stdafx.h at the beginning of all your .cpp files.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1172600
thank you much
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
cb: unreferenced local variable 11 72
What does std::atomic give me? 7 113
Which IDE to use to begin C++ training? 5 59
computer science syllabus 3 70
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now