Forward Declarations/Includes with Template Classes -
Forward Declarations/Includes with Template Classes - "invalid use of incomplete type"
Hey guys. Thanks for clicking. I'm struggling with includes. Basically, I'm trying to make a template class where there is a function that takes in a specific instance of that template. I have made the following contrived example to illustrate this.
Let's say, I have a world of Individuals marked with a templated (generic) type of Data. I have a specific Individual, called a King. And all Individuals should be able to Kneel before a King. Individuals, in general, can be marked as anything. Kings are marked by numbers (the 1st, 2nd king).
The Error
g++ -g -O2 -Wall -Wno-sign-compare -Iinclude -DHAVE_CONFIG_H -c -o Individual.o Individual.cpp g++ -g -O2 -Wall -Wno-sign-compare -Iinclude -DHAVE_CONFIG_H -c -o King.o King.cpp In file included from King.h:3, from King.cpp:2: Individual.h: In member function ?void Individual::KneelBeforeTheKing(King*)?: Individual.h:21: error: invalid use of incomplete type ?struct King? Individual.h:2: error: forward declaration of ?struct King? make: *** [King.o] Error 1 Individual.h (Individual.cpp is empty)
//Individual.h #pragma once class King; #include "King.h" #include #include template class Individual { protected: Data d; public: void Breathe() { printf("Breathing...\n"); }; void KneelBeforeTheKing(King* king) { king->CommandToKneel(); printf("Kneeling...\n"); }; Individual(Data a_d):d(a_d){}; }; King.h
//King.h #pragma once #include "Individual.h" #include #include class King : public Individual { protected: void CommandToKneel(); public: King(int a_d): Individual(a_d) { printf("I am the No. %d King\n", d); }; }; King.cpp
//King.cpp #include "King.h" #include int main(int argc, char** argv) { Individual person("Townsperson"); King* king = new King(1); king->Breathe(); person.Breathe(); person.KneelBeforeTheKing(king); } void King::CommandToKneel() { printf("Kneel before me!\n"); } Makefile
CXX = g++ CXXFLAGS = -g -O2 -Wall -Wno-sign-compare -Iinclude -DHAVE_CONFIG_H OBJS = Individual.o King.o test: $(OBJS) $(CXX) -o $@ $^ clean: rm -rf $(OBJS) test all: test Answer by fredoverflow for Forward Declarations/Includes with Template Classes - "invalid use of incomplete type"
error: invalid use of incomplete type ?struct King?
This means that you have only declared King without defining it. You have circular include issues (Individual.h and King.h include each other). This article should shed some light on the matter.
Answer by CashCow for Forward Declarations/Includes with Template Classes - "invalid use of incomplete type"
Your two classes King and Individual are very tightly coupled.
Having it in two headers like that won't work because both need each other.
If your classes have to be designed that way then:
First define class Individual but do not implement KneelBeforeTheKing, just declare that function.
Then define King
Then implement the method above.
However your design is probably all wrong. For example your template class has many methods that are not dependent on the tamplated type, including KneelBeforeTheKing, and should be refactored out of the template.
Answer by Let_Me_Be for Forward Declarations/Includes with Template Classes - "invalid use of incomplete type"
Well, the problem here is not really related to templates.
You are invoking a specialized functionality of a descendant in the base class. This is almost always a bad design sign.
What about inverting the classes? Something like this (might contain errors):
template < typename PersonType > class Person : PersonType { public: void command_to_kneel() { PersonType::command_to_kneel(); } void kneel_before_king(Person* king) { king->command_to_kneel(); } void breathe() { } }; int main() { Person king; Person knight; knight.kneel_before_king(&king); } Answer by B????? for Forward Declarations/Includes with Template Classes - "invalid use of incomplete type"
You could break the dependency by adding another base class (for example NobleBase) to the class King :
struct NobleBase { virtual void KneelBefore() = 0; }; class King : public Individual, public NobleBase and change the method
void KneelBeforeTheKing(King* king)
to this
void KneelBeforeTheKing(NobleBase* king)
Then you need to include the header for the NobleBase class.
Answer by ajmccluskey for Forward Declarations/Includes with Template Classes - "invalid use of incomplete type"
Syntax and compiler errors aside, I think the biggest issue is that your Individual tells the King to tell itself to kneel.
void KneelBeforeTheKing(King* king) { king->CommandToKneel(); printf("Kneeling...\n"); }; As Let_Me_Be pointed out, this is an issue with design rather than syntax. In reality, a King should decide when Individuals kneel, so it makes sense that any calls to CommandToKneel() come from the King himself, and the set of Individuals be given as an argument to specify who is being commanded.
The syntax issue is that you are attempting to use functionality that hasn't been defined. All the forward declaration for King does is tell the header file for Individual that there is a type called King. At that point the compiler knows nothing about the members of King because you have not included a header file declaring those members, nor have you defined King anywhere before it is used.
However, as has been pointed out already, having any sort of reference to a derived type (i.e. King) in the declaration of its base type (i.e. Individual) is bad design. The base class should know nothing of its derived types.
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:
Post a Comment