Создание структуры с членами структуры в исходном файле - PullRequest
0 голосов
/ 03 ноября 2019

Я новичок в создании пользовательских библиотек и пытаюсь создать библиотеку, которая содержит тип данных struct, который имеет некоторые члены struct. Я хочу, чтобы дочерние элементы использовались только внутренне, но родительская структура со всеми ее компонентами должна быть общедоступной для пользователя. код, который я написал, выглядит примерно так:

#ifndef MYHEADER_H
#define MYHEADER_H
private:
struct child1{
  int thing1;
  int thing2;
};
struct child2{
  char letter;
  int thing3;
};
public:
struct parent{
  int val;
  struct child1 name1;
  struct child2 name2;
};
#endif

, поэтому мой вопрос в том, как должен выглядеть мой исходный файл заголовка .cpp для его создания, и является ли мой заголовок .h даже правильным? Такс заранее

Ответы [ 2 ]

0 голосов
/ 03 ноября 2019

Объявление вашего ребенка в структуре CPP и сохранение его по значению в структуре вашего родителя невозможно. Чтобы дать родительской структуре правильное двоичное представление, необходимо знать, сколько байт принимают члены. Это возможно только в том случае, если детские структуры видны.

Поскольку это C ++, я приму синтаксис к тому, к чему мы привыкли, поэтому вместо struct parent p я просто буду использовать parent p.

У вас есть 2options: Первый делает внутренние внутренние структуры приватными:

#ifndef HEADER_H
#define HEADER_H
#include <memory>
struct child1;
struct child2;
struct parent {
    std::unique_ptr<child1> c1;
    std::unique_ptr<child2> c2;
    ~parent();
};
#endif

Код в Проводник компилятора

Как вы можете видеть, мы перешли к объявлению 2 дочернихструктурирует и помещает unique_ptr в родительскую структуру. Это обеспечивает инкапсуляцию. Я также добавил деструктор для родительской структуры, поскольку ваш компилятор должен иметь возможность вызывать деструктор дочерних структур при уничтожении родительской структуры.

Альтернатива 2 более проста в использовании:

#ifndef MYHEADER_H
#define MYHEADER_H

struct parent {
 private:
  struct child1 {
    int thing1;
    int thing2;
  };
  struct child2 {
    char letter;
    int thing3;
  };

 public:
  int val;
  child1 name1;
  child2 name2;
};

#endif

Код в Проводник компилятора

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

Исходя из моего опыта, я бы рекомендовал сделать все члены структуры / класса родительскими частными. Для детей это не должно быть доступно вне этой структуры / класса в любом случае. Это облегчит поддержку вашего кода.

0 голосов
/ 03 ноября 2019

Хорошо, поехали ...

Давайте сначала отличим объявление от определения. Когда вы говорите int x;, вы сообщаете компьютеру, что существует переменная с именем x, и это целое число. С другой стороны, когда вы говорите x = 5;, вы определяете x как число 5.

То же самое может случиться с функциями, методами, классами и структурами. Следующее:

Объявление функции:

int foo(int, char);

Определение функции:

int foo (int a, char c) { ... do something ... }

И, наконец, структуры:

Объявление структуры:

struct parent;

Определение структуры:

struct parent {
    int thing1, thing2;
    struct child1 c;
};

Хорошо, теперь запомните, что это .h, который будет включать ваша основная программа, затем введите .h только то, что будет использовать основная

#ifndef HEADER_H
#define HEADER_H
struct child1;
struct child2;
struct parent {
    struct child1 c1;
    struct child2 c2;
};
void process_something_internal(struct parent);
#endif

А в вашем .cpp вы можете:

#include "header.h"
#ifdef HEADER_H
struct child1 {
    int t1, t2;
};
struct child2 {
    int t1, t2;
};
void process_something_internal(struct parent p) {
    int = p.child1.t1; // here you can access
    ...
}
#endif
...