Solved

msvc++/appwizard problem

Posted on 1998-09-13
8
243 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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

707 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