2013-09-04 3 views
1

Я хочу сохранить указатель (или ссылку) на другой класс. Это может быть класс, который содержит матрицу указателей на базовый класс, и я хочу иметь возможность использовать публичные функции этого класса внутри функции класса, который имеет указатель (или ссылку) на него. Скажем, это выглядит примерно так:Сохранение указателя на другой класс

base.h

#pragma once 

class base 
{ 
protected: 
    int x; 
    int y; 
public: 
    void setX (int _x) 
    { 
     x=_x; 
    } 
    void setY (int _y) 
    { 
     y=_y; 
    } 
    virtual void f()=0; 
}; 

derived.h

#pragma once 
#include "base.h" 
#include "container.h" 

class derived : public base 
{ 
private: 
    container* c; 
public: 
    derived (container* c, int x, int y) 
     : c(c) 
    { 
     setX(x); 
     setY(y); 
    } 

    void g() 
    { 
     c->doStuff(); 
    } 

    virtual void f() 
    { 
     std::cout<<"f"<<std::endl; 
    } 
}; 

container.h

#pragma once 
#include "base.h" 
#include "derived.h" 

class container 
{ 
private: 
    base*** mat; 
public: 
    container() 
    { 
     mat=new base**[10]; 
     for (int i=0; i<10; ++i) 
      mat[i]=new base*[10]; 

     for (int i=0; i<10; ++i) 
      for (int j=0; j<10; ++i) 
       mat[i][j]=NULL; 

     mat[5][5]=new derived(this, 1, 2); 
    } 

    void doStuff() 
    { 
     std::cout<<"stuff"<<std::endl; 
    } 
}; 

я получаю эти ошибки

derived.h(8): error  C2143: syntax error : missing ';' before '*' 
derived.h(8): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
derived.h(10): error C2061: syntax error : identifier 'container' 
derived.h(10): error C2065: 'c' : undeclared identifier 
derived.h(12): error C2614: 'derived' : illegal member initialization: 'c' is not a base or member 
derived.h(19): error C2065: 'c' : undeclared identifier 
derived.h(19): error C2227: left of '->doStuff' must point to class/struct/union/generic type 
1>   type is ''unknown-type'' 
container.h(20): error C2661: 'derived::derived' : no overloaded function takes 3 arguments 

Я знаю, что я что-то не хватает, и я просто не могу точно определить, что это

ответ

12

Вы циклическую включают зависимость между container.h и derived.h. К счастью, этого можно избежать, так как derived не требуется полное определение container, так что вы можете использовать опережающее объявление вместо включаемой:

#ifndef DERIVED_H_ 
#define DERIVED_H_ 
#include "base.h" 

class container; // fwd declaration 

class derived : public base 
{ 
private: 
    container* c; 

//... as before 

#endif 

Вам нужно будет #include "container.h" в реализации derived.

Как правило, вы должны включать все, что необходимо включить, и не более того.

+4

Я хотел бы отметить, что использование форвардных объявлений - хорошая практика, не только избавляясь от циклических зависимостей. Избыточное '# include' следует избегать всегда, когда это возможно. – LihO

+0

Это исправлено, спасибо. Я не мог заставить его работать, если реализация была также в .h. Еще одна причина иметь отдельные файлы .h и .cpp, но я был слишком ленив для этого. – rndm

Смежные вопросы