2015-03-10 4 views
1

Я пишу библиотеку импорта 3d-активов. (он использует Assimp, кстати). Существует большая сцена, содержащая узлы, содержащие сетки, и каждая сетка содержит материал. Поэтому я создал следующие классы: Scene, Mesh, Material.Класс внутри класса

Только класс сцены должен быть создан и использован кодером, поэтому наиболее разумной задачей было бы объявить Mesh как частный внутри сцены (а также материал как частный внутри Mesh).

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

Мой вопрос в том, есть ли другие подходы к кодированию для достижения моих целей.

+0

Я вообще не фанат 'Friend's, но вы можете сделать' Mesh' конструктор приватным и сделать 'Scene' 'friend', так что ему разрешено создавать экземпляр' Mesh'. – CompuChip

+0

Если можно создать экземпляр «Сцена», как вы можете создать «Mesh» для добавления в «Scene» или «Material» для добавления в 'Mesh', не создавая экземпляр« Mesh »или «Материал» или и то, и другое? Вероятно, было бы лучше, если бы «Сцена» имела некоторые контейнерные методы и позволяла создавать как «Mesh», так и «Material» при необходимости и добавляться в «Сцена», если это необходимо ... – twalberg

+0

@twalberg Сцена получает с файлом импорта. Его ответственность состоит в том, чтобы получить все 3D-данные в память, и для этого используется Mesh и Material. Пользователь не должен заботиться о сетке и материале. – Pilpel

ответ

5

Вы можете посмотреть pimpl idiom. В принципе, выставить только то, что клиент должен и может использовать в открытом интерфейсе, и держать все остальное абстрагируется:

// scene_interface.h 
class SceneImpl; //only forward-declare 
class Scene 
{ 
    // client-visible methods, and that's all 
    // no implementation details 
private: 
    SceneImpl* pImpl; // <- look, the name 
}; 


// scene_impl.h & scene_impl.cpp 
// hidden from the client 
class Mesh 
{ 
    //... 
}; 
class SceneImpl 
{ 
    Mesh* pMesh; 
    //etc. 
}; 
3

Вы можете ограничить частные уроки для неполных деклараций в заголовочном файле (.h), а затем определить их полностью в реализации (.cpp).

Scene.h Заголовок:

class Scene 
{ 
    // ... 
private: 
    class Node; 
    class Mesh; 

    Node *node; 
    Mesh *mesh; 
}; 

Реализация Scene.cpp:

class Scene::Node 
{ 
    // ... 
}; 

class Scene::Mesh 
{ 
    // ... 
}; 

// definitions of member functions ... 
+0

Пользователь все равно сможет создавать новые узлы и сетки. Это не помогает мне – Pilpel

+0

@Pilpel: Пользователь не сможет создать экземпляр 'Node' и 'Mesh'es. Он сможет только объявить им указатели. Если вы этого даже не хотите, вы можете объявить классы внутри 'private' раздела' Scene', а затем префиксные определения с помощью 'Scene ::' в файле реализации. – Matt

+0

@Pilpel: Я изменил свой ответ, чтобы отразить это. – Matt

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