头包含用作另一个类中的成员的类的问题 C++

发布于 2024-10-07 05:26:58 字数 13391 浏览 0 评论 0原文

我的类的定义有问题,可能是因为包含顺序或其他原因。我收到的错误消息是

g++ -I/opt/PDmesa/Mesa-5.0.1/include -I/opt/PDmesa/GLUT-3.7/include -c test.cpp
In file included from prog.h:16,
                 from test.cpp:10:
repeat.h:21: error: ‘Prog’ does not name a type
repeat.h:27: error: ‘Prog’ has not been declared
repeat.h: In constructor ‘Repeat::Repeat(float)’:
repeat.h:34: error: ‘in’ was not declared in this scope
repeat.h:34: error: ‘pg’ was not declared in this scope
repeat.h: In member function ‘virtual void Repeat::Run()’:
repeat.h:44: error: ‘class Repeat’ has no member named ‘pg’
make: *** [test.o] Error 1
% 

这样的问题:我应该做什么才能使用我的两个类? main.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <iterator>
#include "prog.h"
#include "window.h"


using namespace std;

Prog Turtle;

void draw(void)
{
    Turtle.Run();
}


int main ( int argc, char** argv )   // Create Main Function For Bringing It All Together
{
    filebuf fb;
    fb.open (argv[1],ios::in);
    istream input(&fb);
    input>>Turtle;
    fb.close();
    window w(argc,argv);
}

prog.h

#ifndef PROG_H
#define PROG_H

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <iterator>
#include "forward.h"
#include "left.h"
#include "right.h"
#include "jump.h"
#include "repeat.h"

using namespace std;

class Prog
{
    private:

    public:
        Prog();
        ~Prog();
        void Run();
        void clearbuff();
        vector<node*> listing;
        friend istream& operator>> (istream& in, Prog& pro);
};


Prog::Prog()
{
                                                                    //Default constructor
}

Prog::~Prog()
{
                                                                    //Default destructor
}

void Prog::Run()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                ptr->Run();
            }
}

void Prog::clearbuff()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                delete ptr;
            }
}

istream& operator>> (istream& in, Prog& pro)
{
    string tmp, command;
    double value;
    vector<string> text;
    while (in>>tmp)
    {
        for (size_t i=0;i!=tmp.size()+1;++i)
            tmp[i]=toupper(tmp[i]);
        text.push_back(tmp);
    }
    while (!text.empty())
    {
        command=text[0];
        istringstream inpStream(text[1]);
        float value = 0.0;
        if ((inpStream >> value)&&!text.empty())
        {
            if (command=="REPEAT")
                {
                unsigned int x(1), y(0), i(1), pos (0);
                text.erase (text.begin(), text.begin()+2);
                vector<string> reptext;
                if (text[0]=="[")
                {
                    for (i=1;(x!=y)&&i<=text.size();i++)
                        {
                            if (text[i]=="[")
                                ++x;
                            else if (text[i]=="]")
                                ++y;
                            reptext.push_back(text[i]);
                            pos=i;
                            }
                    reptext.erase(reptext.begin()+pos-1,reptext.end());
                    ofstream tempfile ("output.txt");
                    for(i=0; i<reptext.size(); i++)
                    tempfile << reptext[i] << endl;
                    tempfile.close();
                    filebuf rfb;        
                    rfb.open ("output.txt",ios::in);
                    istream rin(&rfb);  
                    pro.listing.push_back(new Repeat(value));
                    Prog ptm;
                    rin>>ptm;
                    rfb.close();
                    text.erase (text.end());
                    text.erase (text.begin(), text.begin()+3);
                }
                else
                cout << "not a bracket found after repeat command --problemo";
                }
            else if (command=="FORWARD")
                {
                    pro.listing.push_back(new Forward(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="LEFT")
                {
                    pro.listing.push_back(new Left(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="RIGHT")
                {
                    pro.listing.push_back(new Right(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="JUMP")
                {
                    pro.listing.push_back(new Jump(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else
                cout << "Unknown command found in the input file!";
             //   text.erase(text.begin());
        }
        else
        {
            cout << " Value after command was not numeric or end of input file was reached!";
        }
    }
return in;
}

#endif // PROG_H

Repeat.h

#ifndef REPEAT_H
#define REPEAT_H

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <iterator>
#include "command.h"
#include "prog.h"

using namespace std;

class Repeat : public command
{
    private:
        Prog pg;
        float repval;
    public:
        Repeat(float value);
        ~Repeat();
        void Run();
        friend istream& operator>> (istream& in, Prog& pro);
};

Repeat::Repeat(float value) : command(value)
{
        this->repval=value;

        for (int i=0;i<value;++i)
            in>>pg; //ctor
}

Repeat::~Repeat()
{

}

void Repeat::Run()
{
        this->pg.Run();
}

#endif // REPEAT_H

你好,我为每个需要的标头添加了单独的 .cpp。现在,如果我删除 #include "prog.h" 以及测试中对 Prog 的所有引用,我会收到以下错误

% make -f makefile3
g++ -I/opt/PDmesa/Mesa-5.0.1/include -I/opt/PDmesa/GLUT-3.7/include -c test.cpp
g++ -c forward.cpp
g++ -c left.cpp
g++ -c right.cpp
g++ -c jump.cpp
g++ -c repeat.cpp
g++ -c prog.cpp
g++ test.o -L/opt/PDmesa/Mesa-5.0.1/lib -L/opt/PDmesa/GLUT-3.7/lib -L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -lXext -lXmu -lXi -lm -o test
test.o: In function `draw()':
test.cpp:(.text+0x2ad): undefined reference to `Prog::Run()'
test.o: In function `main':
test.cpp:(.text+0x33a): undefined reference to `operator>>(std::basic_istream<char, std::char_traits<char> >&, Prog&)'
test.o: In function `__static_initialization_and_destruction_0(int, int)':
test.cpp:(.text+0x443): undefined reference to `Prog::Prog()'
test.cpp:(.text+0x448): undefined reference to `Prog::~Prog()'
collect2: ld returned 1 exit status
make: *** [test] Error 1

test.cpp

#include <iostream>
#include <fstream>
#include <sstream>
#include "prog.h"
#include "window.h"
using namespace std;

Prog Turtle;

void draw(void)
{
    Turtle.Run();
//  Turtle.clearbuff();
}


int main ( int argc, char** argv )   // Create Main Function For Bringing It All Together
{
    filebuf fb;
    fb.open (argv[1],ios::in);
    istream input(&fb);
    input>>Turtle;
    fb.close();
    window w(argc,argv);
}

prog.cpp

#include "prog.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#include "forward.h"
#include "left.h"
#include "right.h"
#include "jump.h"
#include "repeat.h"

Prog::Prog()
{

}

Prog::~Prog()
{

}

void Prog::Run()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                ptr->Run();
            }
}

void Prog::clearbuff()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                delete ptr;
            }
}

istream& operator>> (istream& in, Prog& pro)
{
    string tmp, command;
    double value;
    vector<string> text;
    while (in>>tmp)
    {
        for (size_t i=0;i!=tmp.size()+1;++i)
            tmp[i]=toupper(tmp[i]);
        text.push_back(tmp);
    }
    while (!text.empty())
    {
        command=text[0];
        istringstream inpStream(text[1]);
        float value = 0.0;
        if ((inpStream >> value)&&!text.empty())
        {
            if (command=="REPEAT")
                {
                unsigned int x(1), y(0), i(1), pos (0);
                text.erase (text.begin(), text.begin()+2);
                vector<string> reptext;
                if (text[0]=="[")
                {
                    for (i=1;(x!=y)&&i<=text.size();i++)
                        {
                            if (text[i]=="[")
                                ++x;
                            else if (text[i]=="]")
                                ++y;
                            reptext.push_back(text[i]);
                            pos=i;
                            }
                    reptext.erase(reptext.begin()+pos-1,reptext.end());
                    ofstream tempfile ("output.txt");
                    for(i=0; i<reptext.size(); i++)
                    tempfile << reptext[i] << endl;
                    tempfile.close();
                    filebuf rfb;        
                    rfb.open ("output.txt",ios::in);
                    istream rin(&rfb);  
                    //pro.listing.push_back(new Repeat(value,rin));
                    Prog ptm;
                    rin>>ptm;
                    rfb.close();
                    for (int rp=0;rp<value;rp++)
                        {
                            cout << rp << endl;
                            for (i=0;i<ptm.listing.size();i++)
                                pro.listing.push_back(ptm.listing.at(i));
                        }
                    text.erase (text.end());
                    text.erase (text.begin(), text.begin()+3);
                }
                else
                cout << "not a bracket found after repeat command --problemo";
                }
            else if (command=="FORWARD")
                {
                    pro.listing.push_back(new Forward(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="LEFT")
                {
                    pro.listing.push_back(new Left(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="RIGHT")
                {
                    pro.listing.push_back(new Right(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="JUMP")
                {
                    pro.listing.push_back(new Jump(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else
                cout << "Unknown command found in the input file!";
             //   text.erase(text.begin());
        }
        else
        {
            cout << " Value after command was not numeric or end of input file was reached!";
        }
    }
return in;
}

prog.h

#ifndef PROG_H
#define PROG_H

#include <iostream>
#include <fstream>
#include <vector>
#include "node.h"
using namespace std;

class Repeat;

class Prog
{
    private:

    public:
        Prog();
        ~Prog();
        void Run();
        void clearbuff();
        friend istream& operator>> (istream& in, Prog& pro);
        vector<node*> listing;
};

#endif // PROG_H

Repeat.cpp

#include "repeat.h"
using namespace std;

Repeat::Repeat(float value, istream in) : command(value)
{
        this->repval=value;
        for (int i=0;i<value;++i)
            in>>pg; //ctor
}

Repeat::~Repeat()
{

}

void Repeat::Run()
{
        this-> pg.Run();
}

Repeat.h

#ifndef REPEAT_H
#define REPEAT_H

#include <iostream>
#include <fstream>
#include "command.h"
#include "prog.h"
using namespace std;

class Prog;

class Repeat : public command
{
    private:
        Prog pg;
        float repval;
    public:
        Repeat(float value, istream in);
        ~Repeat();
        void Run();
        friend istream& operator>> (istream& in, Prog& pro);
};

#endif // REPEAT_H

它可以正确编译,但它实际上不起作用。另外,我真正想做的是从 prog.cpp 中取消注释 pro.listing.push_back(new Repeat(value,rin)); 并删除接下来的 10 行。这一行是上一行的问题设计。我怀疑我又对整个标题做了一些错误的事情

I have a problem with the definitions of my classes, probably because of the inclusion order or something.the error msg i receive is

g++ -I/opt/PDmesa/Mesa-5.0.1/include -I/opt/PDmesa/GLUT-3.7/include -c test.cpp
In file included from prog.h:16,
                 from test.cpp:10:
repeat.h:21: error: ‘Prog’ does not name a type
repeat.h:27: error: ‘Prog’ has not been declared
repeat.h: In constructor ‘Repeat::Repeat(float)’:
repeat.h:34: error: ‘in’ was not declared in this scope
repeat.h:34: error: ‘pg’ was not declared in this scope
repeat.h: In member function ‘virtual void Repeat::Run()’:
repeat.h:44: error: ‘class Repeat’ has no member named ‘pg’
make: *** [test.o] Error 1
% 

so the question what should I do so i can use both of my classes?
main.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <iterator>
#include "prog.h"
#include "window.h"


using namespace std;

Prog Turtle;

void draw(void)
{
    Turtle.Run();
}


int main ( int argc, char** argv )   // Create Main Function For Bringing It All Together
{
    filebuf fb;
    fb.open (argv[1],ios::in);
    istream input(&fb);
    input>>Turtle;
    fb.close();
    window w(argc,argv);
}

prog.h

#ifndef PROG_H
#define PROG_H

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <iterator>
#include "forward.h"
#include "left.h"
#include "right.h"
#include "jump.h"
#include "repeat.h"

using namespace std;

class Prog
{
    private:

    public:
        Prog();
        ~Prog();
        void Run();
        void clearbuff();
        vector<node*> listing;
        friend istream& operator>> (istream& in, Prog& pro);
};


Prog::Prog()
{
                                                                    //Default constructor
}

Prog::~Prog()
{
                                                                    //Default destructor
}

void Prog::Run()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                ptr->Run();
            }
}

void Prog::clearbuff()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                delete ptr;
            }
}

istream& operator>> (istream& in, Prog& pro)
{
    string tmp, command;
    double value;
    vector<string> text;
    while (in>>tmp)
    {
        for (size_t i=0;i!=tmp.size()+1;++i)
            tmp[i]=toupper(tmp[i]);
        text.push_back(tmp);
    }
    while (!text.empty())
    {
        command=text[0];
        istringstream inpStream(text[1]);
        float value = 0.0;
        if ((inpStream >> value)&&!text.empty())
        {
            if (command=="REPEAT")
                {
                unsigned int x(1), y(0), i(1), pos (0);
                text.erase (text.begin(), text.begin()+2);
                vector<string> reptext;
                if (text[0]=="[")
                {
                    for (i=1;(x!=y)&&i<=text.size();i++)
                        {
                            if (text[i]=="[")
                                ++x;
                            else if (text[i]=="]")
                                ++y;
                            reptext.push_back(text[i]);
                            pos=i;
                            }
                    reptext.erase(reptext.begin()+pos-1,reptext.end());
                    ofstream tempfile ("output.txt");
                    for(i=0; i<reptext.size(); i++)
                    tempfile << reptext[i] << endl;
                    tempfile.close();
                    filebuf rfb;        
                    rfb.open ("output.txt",ios::in);
                    istream rin(&rfb);  
                    pro.listing.push_back(new Repeat(value));
                    Prog ptm;
                    rin>>ptm;
                    rfb.close();
                    text.erase (text.end());
                    text.erase (text.begin(), text.begin()+3);
                }
                else
                cout << "not a bracket found after repeat command --problemo";
                }
            else if (command=="FORWARD")
                {
                    pro.listing.push_back(new Forward(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="LEFT")
                {
                    pro.listing.push_back(new Left(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="RIGHT")
                {
                    pro.listing.push_back(new Right(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="JUMP")
                {
                    pro.listing.push_back(new Jump(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else
                cout << "Unknown command found in the input file!";
             //   text.erase(text.begin());
        }
        else
        {
            cout << " Value after command was not numeric or end of input file was reached!";
        }
    }
return in;
}

#endif // PROG_H

repeat.h

#ifndef REPEAT_H
#define REPEAT_H

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <sstream>
#include <iterator>
#include "command.h"
#include "prog.h"

using namespace std;

class Repeat : public command
{
    private:
        Prog pg;
        float repval;
    public:
        Repeat(float value);
        ~Repeat();
        void Run();
        friend istream& operator>> (istream& in, Prog& pro);
};

Repeat::Repeat(float value) : command(value)
{
        this->repval=value;

        for (int i=0;i<value;++i)
            in>>pg; //ctor
}

Repeat::~Repeat()
{

}

void Repeat::Run()
{
        this->pg.Run();
}

#endif // REPEAT_H

hello I added separate .cpp for each header that needs one. now I receive the following error

% make -f makefile3
g++ -I/opt/PDmesa/Mesa-5.0.1/include -I/opt/PDmesa/GLUT-3.7/include -c test.cpp
g++ -c forward.cpp
g++ -c left.cpp
g++ -c right.cpp
g++ -c jump.cpp
g++ -c repeat.cpp
g++ -c prog.cpp
g++ test.o -L/opt/PDmesa/Mesa-5.0.1/lib -L/opt/PDmesa/GLUT-3.7/lib -L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -lXext -lXmu -lXi -lm -o test
test.o: In function `draw()':
test.cpp:(.text+0x2ad): undefined reference to `Prog::Run()'
test.o: In function `main':
test.cpp:(.text+0x33a): undefined reference to `operator>>(std::basic_istream<char, std::char_traits<char> >&, Prog&)'
test.o: In function `__static_initialization_and_destruction_0(int, int)':
test.cpp:(.text+0x443): undefined reference to `Prog::Prog()'
test.cpp:(.text+0x448): undefined reference to `Prog::~Prog()'
collect2: ld returned 1 exit status
make: *** [test] Error 1

test.cpp

#include <iostream>
#include <fstream>
#include <sstream>
#include "prog.h"
#include "window.h"
using namespace std;

Prog Turtle;

void draw(void)
{
    Turtle.Run();
//  Turtle.clearbuff();
}


int main ( int argc, char** argv )   // Create Main Function For Bringing It All Together
{
    filebuf fb;
    fb.open (argv[1],ios::in);
    istream input(&fb);
    input>>Turtle;
    fb.close();
    window w(argc,argv);
}

prog.cpp

#include "prog.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#include "forward.h"
#include "left.h"
#include "right.h"
#include "jump.h"
#include "repeat.h"

Prog::Prog()
{

}

Prog::~Prog()
{

}

void Prog::Run()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                ptr->Run();
            }
}

void Prog::clearbuff()
{
    size_t sz=this->listing.size();
    for (size_t it=0;it<sz;it++)
            {
                node* ptr = this->listing.at(it);
                delete ptr;
            }
}

istream& operator>> (istream& in, Prog& pro)
{
    string tmp, command;
    double value;
    vector<string> text;
    while (in>>tmp)
    {
        for (size_t i=0;i!=tmp.size()+1;++i)
            tmp[i]=toupper(tmp[i]);
        text.push_back(tmp);
    }
    while (!text.empty())
    {
        command=text[0];
        istringstream inpStream(text[1]);
        float value = 0.0;
        if ((inpStream >> value)&&!text.empty())
        {
            if (command=="REPEAT")
                {
                unsigned int x(1), y(0), i(1), pos (0);
                text.erase (text.begin(), text.begin()+2);
                vector<string> reptext;
                if (text[0]=="[")
                {
                    for (i=1;(x!=y)&&i<=text.size();i++)
                        {
                            if (text[i]=="[")
                                ++x;
                            else if (text[i]=="]")
                                ++y;
                            reptext.push_back(text[i]);
                            pos=i;
                            }
                    reptext.erase(reptext.begin()+pos-1,reptext.end());
                    ofstream tempfile ("output.txt");
                    for(i=0; i<reptext.size(); i++)
                    tempfile << reptext[i] << endl;
                    tempfile.close();
                    filebuf rfb;        
                    rfb.open ("output.txt",ios::in);
                    istream rin(&rfb);  
                    //pro.listing.push_back(new Repeat(value,rin));
                    Prog ptm;
                    rin>>ptm;
                    rfb.close();
                    for (int rp=0;rp<value;rp++)
                        {
                            cout << rp << endl;
                            for (i=0;i<ptm.listing.size();i++)
                                pro.listing.push_back(ptm.listing.at(i));
                        }
                    text.erase (text.end());
                    text.erase (text.begin(), text.begin()+3);
                }
                else
                cout << "not a bracket found after repeat command --problemo";
                }
            else if (command=="FORWARD")
                {
                    pro.listing.push_back(new Forward(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="LEFT")
                {
                    pro.listing.push_back(new Left(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="RIGHT")
                {
                    pro.listing.push_back(new Right(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else if (command=="JUMP")
                {
                    pro.listing.push_back(new Jump(value));
                    text.erase (text.begin(), text.begin()+2);
                }
            else
                cout << "Unknown command found in the input file!";
             //   text.erase(text.begin());
        }
        else
        {
            cout << " Value after command was not numeric or end of input file was reached!";
        }
    }
return in;
}

prog.h

#ifndef PROG_H
#define PROG_H

#include <iostream>
#include <fstream>
#include <vector>
#include "node.h"
using namespace std;

class Repeat;

class Prog
{
    private:

    public:
        Prog();
        ~Prog();
        void Run();
        void clearbuff();
        friend istream& operator>> (istream& in, Prog& pro);
        vector<node*> listing;
};

#endif // PROG_H

repeat.cpp

#include "repeat.h"
using namespace std;

Repeat::Repeat(float value, istream in) : command(value)
{
        this->repval=value;
        for (int i=0;i<value;++i)
            in>>pg; //ctor
}

Repeat::~Repeat()
{

}

void Repeat::Run()
{
        this-> pg.Run();
}

repeat.h

#ifndef REPEAT_H
#define REPEAT_H

#include <iostream>
#include <fstream>
#include "command.h"
#include "prog.h"
using namespace std;

class Prog;

class Repeat : public command
{
    private:
        Prog pg;
        float repval;
    public:
        Repeat(float value, istream in);
        ~Repeat();
        void Run();
        friend istream& operator>> (istream& in, Prog& pro);
};

#endif // REPEAT_H

if I remove #include "prog.h" and all references to Prog from test it compiles correctly but it doesnt actually work. also what I actually want to do is uncomment pro.listing.push_back(new Repeat(value,rin)); from prog.cpp and remove the next 10 lines.this line was the problem with the previous design. I supsect that Im doing again something wrong with the whole header thing

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

[浮城] 2024-10-14 05:26:58

这里的问题是你有循环引用。

您可以将 #include 语句视为简单地将该文件的内容剪切并粘贴到放置该指令的文件中。您可以做几件事。

#1 - 将您的实现放入“.cpp”文件

您的“Prog”类定义未提及Repeat。如果您有一个包含实际方法定义的“prog.cpp”文件,则可以在其中#include "repeat.h",这样就不会有任何问题。

其他技巧包括前向声明、在需要发生循环引用的类定义中使用指针等。

The problem here is that you have circular references.

You can think of a #include statement as simply cutting and pasting the contents of that file into the file where the directive is placed. There are several things you can do.

#1 - Put your implementation in a '.cpp' file

Your 'Prog' class definition does not mention Repeat. If you had a 'prog.cpp' file with the actual method definitions in it, you could #include "repeat.h" there and you wouldn't have any problems.

Other tricks include forward declarations, using pointers in your class defenition where a circular reference needs to take place, etc.

倒带 2024-10-14 05:26:58
  1. 您正在头文件中实现类的成员函数。 不要这样做。这就是 .cpp 文件的用途。

  2. 您有一个循环包含。 prog.h 尝试#include "repeat.h",repeat.h 尝试#include "prog.h"。其中一个将在另一个之前得到处理,然后标头防护将阻止另一个被处理。最终的结果是,您最终没有#include 包含您期望的所有内容,并且缺少声明。

一旦我们解决了第一个问题,这个问题就很容易解决,因为这样我们就不再需要知道 Prog 标头中的 Repeat 了,只需删除该 #include 语句。在 .cpp 文件中,我们包含这两个标头,并且没有问题。

我还想推荐您参考 http://www.gamedev.net/reference/articles /article1798.asp 详细解释了头文件与实现文件的所有常见问题。

  1. You are implementing the member functions for your classes in the header files. Don't do that. That is what the .cpp files are for.

  2. You have a circular include. prog.h attempts to #include "repeat.h", and repeat.h attempts to #include "prog.h". One of these will get processed before the other, and then the header guards will prevent the other one from being processed. The net effect is that you don't end up #include ing everything you expected to, and then you have missing declarations.

This is easy to fix once we fix the first problem, because then we will no longer need to know about Repeat in the Prog header, and can just remove that #include statement. In the .cpp file, we include both headers, and there is no problem.

I would also like to refer you to http://www.gamedev.net/reference/articles/article1798.asp which explains all the common issues with header vs. implementation files in detail.

风情万种。 2024-10-14 05:26:58

在 prog.h 中,您在文件顶部包含了repeat.h。

主体repeat.h 没有看到任何Prog.h 定义。

尝试直接让main.cpp包含repeat.h
从 prog.h 中删除 #include "repeat.h"

In prog.h you include repeat.h at the top of the file.

The body repeat.h doesn't see any of the Prog.h definitions.

Try having main.cpp include repeat.h directly
Remove #include "repeat.h" from prog.h

内心旳酸楚 2024-10-14 05:26:58

我可以补充一点,如果两个类的声明相互引用,因此将实现移动到 *.cpp 文件并没有真正的帮助(尽管它仍然是必要的),那么您应该使用前向声明而不是包含,如下所示

// in repeat.h
class Prog;
...
friend istream& operator>> (istream& in, Prog& pro);

// in prog.h
class Repeat;
...
void someMethodThatUsesRepeat(Repeat *rep);

:即使您没有两个相互引用的类,使用前向声明仍然可能有助于加快编译速度,因为编译器不必每次包含 Repeat.h 时都编译两个标头。

I can add that if both classes' declaration referenced each other so moving the implementations to *.cpp files wouldn't really help (although it still would be necessary), then you should have used forward declarations instead of includes, like this:

// in repeat.h
class Prog;
...
friend istream& operator>> (istream& in, Prog& pro);

// in prog.h
class Repeat;
...
void someMethodThatUsesRepeat(Repeat *rep);

Note that even if you don't have two classes referencing each other, using forward declarations may still be useful to speed up compilation since the compiler won't have to compile both headers each time when repeat.h is included.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文