-4

I am using C++ to make a basic family with polymorphism. However, I get errors when I compile, and I am not sure how to correct them (I say class dependency, as Parent and Child both depend on each other before the other is created):

error C2061: syntax error : identifier 'Parent'

error C2143: syntax error : missing ';' before '*'

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

error C2065: 'parent' : undeclared identifier

error C2065: 'name' : undeclared identifier

error C2614: 'Child' : illegal member initialization: 'par' is not a base or member

error C2065: 'par' : undeclared identifier

error C2227: left of '->addChild' must point to class/struct/union/generic type

error C2065: 'par' : undeclared identifier

error C2227: left of '->Name' must point to class/struct/union/generic type

error C2661: 'Child::Child' : no overloaded function takes 2 arguments

error C2065: 'par' : undeclared identifier

error C2227: left of '->Name' must point to class/struct/union/generic type

/* Polymorphism Family */
#include <iostream>
#include <vector>
class Child{
public:
    Child(Parent* parent, char* name) : par(parent), Name(name){ par->addChild(this); };
    Parent* par;
    char* Name;
    virtual void Speak(void){
        std::cout << "I am a child, my name is " << Name << " and my parent's name is " << par->Name << std::endl;
    }
};
class Parent{
public:
    Parent(char* name) : Name(name){};
    char* Name;
    std::vector<Child*> Children;
    virtual void Speak(void){
        std::cout << "I am a parent called " << Name << std::endl;
        if(Children.size() == 0){
            std::cout << "I have no children" << std::endl;
        }
        else{
            std::cout << "I have " << Children.size() << " children:" << std::endl;
            for(auto c : Children){
                std::cout << c->Name;
            }
        }
    }
    void addChild(Child* child){
        Children.push_back(child);
    }
};
class Father : public Parent{
public:
    Father(char* name) : Parent(name){}
    void Speak(void){
        std::cout << "I am a father called " << Name << std::endl;
        if(Children.size() == 0){
            std::cout << "I have no children" << std::endl;
        }
        else{
            std::cout << "I have " << Children.size() << " children:" << std::endl;
            for(Child* c : Children){
                std::cout << c->Name;
            }
        }
    }
};
class Son : public Child{
public:
    Son(Parent* parent, char* name) : Child(parent, name){}
    void Speak(void){
        std::cout << "I am a son, my name is " << Name << " and my parent's name is " << par->Name << std::endl;
    }
};
int main(void){
    Father* Dad = new Father("James");
    Dad->Speak();
    Son* John = new Son(Dad, "John");
    John->Speak();
    Dad->Speak();
    delete[] Dad, John;
    getchar();
    return (0);
}

Edit: I have 2 errors now:

/* Polymorphism Family */
#include <iostream>
#include <vector>

class Parent;

class Child{
public:
    Child(Parent* parent, char* name);
    Parent* par;
    char* Name;
    virtual void Speak(void){
        std::cout << "I am a child, my name is " << Name << " and my parent's name is " << par->Name << std::endl;
    }
};

class Parent{
public:
    Parent(char* name) : Name(name){};
    char* Name;
    std::vector<Child*> Children;
    virtual void Speak(void){
        std::cout << "I am a parent called " << Name << std::endl;
        if(Children.size() == 0){
            std::cout << "I have no children" << std::endl;
        }
        else{
            std::cout << "I have " << Children.size() << " child(ren):" << std::endl;
            for(auto c : Children){
                std::cout << c->Name << std::endl;
            }
        }
    }
    void addChild(Child* child){
        Children.push_back(child);
    }
};

Child::Child(Parent* parent, char* name){
    Child::par = parent;
    Child::Name = name;
    par->addChild(this); 
};

class Father : public Parent{
public:
    Father(char* name) : Parent(name){}
    void Speak(void){
        std::cout << "I am a father called " << Name << std::endl;
        if(Children.size() == 0){
            std::cout << "I have no children" << std::endl;
        }
        else{
            std::cout << "I have " << Children.size() << "child(ren):" << std::endl;
            for(auto c : Children){
                std::cout << c->Name << std::endl;
            }
        }
    }
};
class Son : public Child{
public:
    Son(Parent* parent, char* name) : Child(parent, name){}
    void Speak(void){
        std::cout << "I am a son, my name is " << Name << " and my parent's name is " << par->Name << std::endl;
    }
};
int main(void){
    Father* Dad = new Father("James");
    Dad->Speak();
    Son* John = new Son(Dad, "John");
    John->Speak();
    Dad->Speak();
    delete[] Dad, John;
    getchar();
    return (0);
}
kero
  • 10,647
  • 5
  • 41
  • 51
user2976089
  • 347
  • 1
  • 5
  • 14
  • 1
    Use forward declarations to break cyclic dependencies. Also, `delete[] Dad, John` does not do what you think – Andy Prowl Dec 24 '13 at 16:17
  • 2
    Your code is very bad. See [_Modern C++_](http://klmr.me/slides/modern-cpp/#1) and [_The Definitive C++ Book Guide and List_](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). –  Dec 24 '13 at 16:18
  • Your compiler should output line numbers on it's error messages. There's a good reason for that! – Roddy Dec 24 '13 at 20:59
  • Hi. @user2976089 have you checked this code by online compiler with options i'd provided in additional part of my answer? – nndru Dec 28 '13 at 11:33

1 Answers1

2

Your Child class uses Parent class that hasn't been defined yet (not above on code, prior to Child or in some of included files). To fix this issue just declare Parent class before (or "above") Child. For example:

class Parent;

//child class declaration as posted in your code and other classes include Parent.
class Child{
public:
    Child(Parent* parent, char* name) : par(parent), Name(name){ par->addChild(this); };
    Parent* par;
...

Hope this helps.

[Added] Here is working example of code asked by author:

    #include <iostream>
#include <vector>

using namespace std;

class Child;

class Parent {

public:
    Parent(const char* name) : Name(name){};
    const char* Name;
    std::vector<Child*> Children;

    void Speak(void);
    void addChild(Child* child);
};

class Child{
public:
    Child(Parent* parent, const char* name) {
        Child::par = parent;
        Child::Name = name;
        par->addChild(this); 
    }

    Parent* par;
    const char* Name;
    virtual void Speak(void){
        std::cout << "I am a child, my name is " << Name << " and my parent's name is " << par->Name << std::endl;
    }
};

void Parent::Speak(void){
        std::cout << "I am a parent called " << Name << std::endl;
        if(Children.size() == 0){
            std::cout << "I have no children" << std::endl;
        }
        else{
            std::cout << "I have " << Children.size() << " child(ren):" << std::endl;
            for(auto c : Children){
                std::cout << c->Name << std::endl;
            }
        }
    }


void Parent::addChild(Child* child) {
        Children.push_back(child);
    }

class Father : public Parent{
public:
    Father(const char* name) : Parent(name){}
    void Speak(void){
        std::cout << "I am a father called " << Name << std::endl;
        if(Children.size() == 0){
            std::cout << "I have no children" << std::endl;
        }
        else{
            std::cout << "I have " << Children.size() << "child(ren):" << std::endl;
            for(auto c : Children){
                std::cout << c->Name << std::endl;
            }
        }
    }
};

class Son : public Child{
public:
    Son(Parent* parent, const char* name) : Child(parent, name){}
    void Speak(void){
        std::cout << "I am a son, my name is " << Name << " and my parent's name is " << par->Name << std::endl;
    }
};

int main(int argc, char** argv){

    //i suggest you to use stack-located variables against heap-located
    Father Dad("James");
    Dad.Speak();

    Son John(&Dad, "John");
    John.Speak();
    Dad.Speak();    

    // Father* Dad = new Father("James");
    // Dad->Speak();
    // Son* John = new Son(Dad, "John");
    // John->Speak();
    // Dad->Speak();
    // delete Dad; 
    // delete John;
    //getchar();
    return (0);
}

Output by online cpp editor

Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1

Executing the program....
$demo 
I am a father called James
I have no children
I am a son, my name is John and my parent's name is James
I am a father called James
I have 1child(ren):
John
nndru
  • 2,057
  • 21
  • 16
  • I still get 4 errors though – user2976089 Dec 24 '13 at 16:20
  • 1
    Please, post that errors. – nndru Dec 24 '13 at 16:21
  • `Use of undefined parent` twice, `left of ->addChild must point to a class/struct/union/generic type`, `left of -> name must point to a...` – user2976089 Dec 24 '13 at 16:25
  • You should implement `Child` class constructor (where you invoke `Parent`) after you've implemented `Parent` class. E.g. `class Parent; class Child { Child(); ... } class Parent { ... } ... //"below" "Parent" class definition public Child::Child(Parent* parent, char* name) { /* invoke parent's method here */ }`. Hope this helps. – nndru Dec 24 '13 at 16:28
  • I have edited it, but I still have two errors - `Use of undefined parent` and `left of -> name must point to a...` – user2976089 Dec 24 '13 at 18:20
  • Ok. You should add property `Name` with public access to `Parent` class declaration that located above `Child` class declaration. So `Child` class will know about `Parent`'s property `Name`. – nndru Dec 24 '13 at 19:20
  • How would I do that please - +1 and accepted answer if you can? – user2976089 Dec 24 '13 at 19:33