I have tried to implement the state pattern
but the linker raises the error: can't resolve symbols.
For me it is very frustrating, because I tried several hours to solve
this problem.
Is anybody willing to analyze my code what is going wrong.
It seems I have the chicken egg problem: Who was first the chicken or
the egg.
This seems to be the problem, but from my point of view,
this is very common when designing a problem.
I appreciate your comments.
Zeh Mau
Can you post a small example that shows the problem? How big is your code?
#ifndef __CAusverkauftZustand__
#define __CAusverkauftZustand__
#include "CZustand.h"
class CKaugummiAutomat;
class CAusverkauftZustand : public CZustand
{
public:
CKaugummiAutomat * theKaugummiAutomat;
CAusverkauftZustand(CKaugummiAutomat *);
virtual void muenzeEinwerfen();
virtual void muenzeAuswerfen();
virtual void griffDrehen();
virtual void kugelAusgeben();
};
#include "CKaugummiAutomat.h"
#endif
----------------------------------------------------------------
CZustand.h
#ifndef __CZustand__
#define __CZustand__
class CZustand
{
public:
virtual void muenzeEinwerfen() = 0;
virtual void muenzeAuswerfen() = 0;
virtual void griffDrehen() = 0;
virtual void kugelAusgeben() = 0;
};
#endif
----------------------------------------------------------------
CKaugummi.h
#ifndef __CKaugummiAutomat__
#define __CKaugummiAutomat__
#include "CZustand.h"
class CAusverkauftZustand;
class CKaugummiAutomat
{
public:
CKaugummiAutomat(int);
CZustand * theAusverkauftZustand;
CZustand * theZustand;
int iAnzahlKaugummis;
void muenzeEinwerfen();
void griffDrehen();
void kugelFreigeben();
void setZustand(CZustand *);
void getAnzahlKaugummis();
CZustand * getAusverkauftZustand();
};
#include "CAusverkauftZustand.h"
#endif
----------------------------------------------------------------
stdafx.h
// stdafx.h : Includedatei für Standardsystem-Includedateien
// oder häufig verwendete projektspezifische Includedateien,
// die nur in unregelmäßigen Abständen geändert werden.
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <iostream>
using namespace std;
// TODO: Hier auf zusätzliche Header, die das Programm erfordert,
verweisen.
----------------------------------------------------------------
targetver.h
#pragma once
// Die folgenden Makros definieren die mindestens erforderliche
Plattform. Die mindestens erforderliche Plattform
// ist die früheste Windows-, Internet Explorer-Version usw., die über
die erforderlichen Features zur Ausführung
// Ihrer Anwendung verfügt. Die Makros aktivieren alle Funktionen, die
auf den Plattformversionen bis
// einschließlich der angegebenen Version verfügbar sind.
// Ändern Sie folgende Definitionen für Plattformen, die älter als die
unten angegebenen sind.
// Unter MSDN finden Sie die neuesten Informationen über die
entsprechenden Werte für die unterschiedlichen Plattformen.
#ifndef _WIN32_WINNT // Gibt an, dass Windows Vista die
mindestens erforderliche Plattform ist.
#define _WIN32_WINNT 0x0600 // Ändern Sie den entsprechenden Wert,
um auf andere Versionen von Windows abzuzielen.
#endif
----------------------------------------------------------------
CAusverkauft.cpp
#include "CAusverkauftZustand.h"
#include "CKaugummiAutomat.h"
#include <iostream>
CAusverkauftZustand::CAusverkauftZustand(CKaugummiAutomat * p)
{
theKaugummiAutomat = p;
p->setZustand(p->getAusverkauftZustand());
}
void CAusverkauftZustand::muenzeEinwerfen()
{
std::cout << "\nDer Automat ist ausverkauft.";
}
void CAusverkauftZustand::muenzeAuswerfen()
{
std::cout << "\nSie haben keine Muenze eingeworfen.";
}
void CAusverkauftZustand::griffDrehen()
{
std::cout << "\nEs sind keine Kugeln da.";
}
void CAusverkauftZustand::kugelAusgeben()
{
std::cout << "\nEs wird keine Kugel ausgegebn.";
}
----------------------------------------------------------------
CKaugummi.cpp
#include "CKaugummiAutomat.h"
#include "CAusverkauftZustand.h"
#include <iostream>
CKaugummiAutomat::CKaugummiAutomat(int iAnzahl)
{
iAnzahlKaugummis = iAnzahl;
theAusverkauftZustand = new CAusverkauftZustand(this);
theZustand = theAusverkauftZustand;
if (iAnzahlKaugummis > 0)
{
}
else
{
theZustand = theAusverkauftZustand;
}
}
void CKaugummiAutomat::muenzeEinwerfen()
{
theZustand->muenzeEinwerfen();
}
void CKaugummiAutomat::griffDrehen()
{
theZustand->griffDrehen();
}
void CKaugummiAutomat::kugelFreigeben()
{
theZustand->kugelAusgeben();
if (iAnzahlKaugummis != 0)
{
iAnzahlKaugummis--;
}
}
void CKaugummiAutomat::setZustand(CZustand * p)
{
theZustand = p;
}
void CKaugummiAutomat::getAnzahlKaugummis()
{
std::cout << "\nEs gibt " << iAnzahlKaugummis << " Kaugummis.";
}
CZustand * CKaugummiAutomat::getAusverkauftZustand()
{
return theAusverkauftZustand;
}
----------------------------------------------------------------
State-pattern.cpp
#include "stdafx.h"
#include "CKaugummiAutomat.h"
int _tmain(int argc, _TCHAR* argv[])
{
CKaugummiAutomat * A = new CKaugummiAutomat(5);
A->kugelFreigeben();
A->muenzeEinwerfen();
A->griffDrehen();
_getch();
return 0;
}
----------------------------------------------------------------
stdafx.cpp
// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
// State-Pattern.pch ist der vorkompilierte Header.
// stdafx.obj enthält die vorkompilierten Typinformationen.
#include "stdafx.h"
// TODO: Auf zusätzliche Header verweisen, die in STDAFX.H
// und nicht in dieser Datei erforderlich sind.
Well, here is your problem. You're using reserved names for your own
macros. Any name that has two consecutive underscores or begins with an
underscore and a capital letter is reserved by the implementation.
On a serious note, have you tried putting everything in one file? Do
you still have the same problem? If you haven't tried it, do. If you
still have the same linker problem, check your libraries. Also, read
the FAQ section 5.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
More likely they were generated by the IDE...
> Any name that has two consecutive underscores or begins with an
>underscore and a capital letter is reserved by the implementation.
.. and are therefore deemed to be part of the implementation.
>
>On a serious note, have you tried putting everything in one file? Do
>you still have the same problem? If you haven't tried it, do. If you
>still have the same linker problem, check your libraries. Also, read
>the FAQ section 5.
In particular: _which_ symbols can't the linker resolve?
--
Richard Herring
Uh... No. IDE is not part of the implementation. We're talking the
preprocessor, the compiler, and the linker. Code generators are not
covered by the Standard.
[..]
To be sure... but are they _excluded_? Don't forget the I in IDE stands
for "integrated" ;-)
--
Richard Herring
I suggest you have a look at the wikipedia entry for "State pattern".
It has a quite nice example in C++ that should cover your needs.
Well, if I take the code generated by the IDE to another compiler, isn't
it supposed to work?
And "integrated" doesn't necessarily mean "into the compiler", I believe
it means "everything in one place" (which isn't always A GOOD IDEA(tm)). :-)
Paraphrasing one saying, "You can take the code out of the IDE, but you
can't take the IDE out of the code"...