Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

msvc++/appwizard problem

Posted on 1998-09-13
8
Medium Priority
?
270 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 400 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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
 
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
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.

721 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