Форум программистов, компьютерный форум CyberForum.ru

Где создавать объекты классов? - C++

Восстановить пароль Регистрация
 
 
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 11:28     Где создавать объекты классов? #1
Здравствуйте. Подскажите, если есть много классов, объявленных в заголовочных файлах,
а определенных в *.cpp - файлах, и для каждого класса создается объект, где эти объекты правильно создавать.
Я создаю их там где они оказываются нужны в первый раз. Например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// A.cpp
#include "B.cpp"
class A {
    B objB;
};
 
// B.cpp
#include "A.cpp"
#include "C.cpp"
class B {
    A objA;
    C objC;
};
 
//C.cpp
#include "B.cpp"
class C {
    B objB;
};
А то у меня создание объектов разбросано по всей программе,
может это нужно делать где-то в одном месте? (обычно подключаю *.h - файлы, а не *.cpp, как здесь,
не стал писать, чтоб упростить пример)

И правильно-ли, что объекты нужно создавать только в *.cpp - файлах, а в *.h - нельзя?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 13:04     Где создавать объекты классов? #2
Цитата Сообщение от dimkaok Посмотреть сообщение
обычно подключаю *.h - файлы, а не *.cpp, как здесь,
не стал писать, чтоб упростить пример
Не делайте так, это не упрощает пример, а, напротив, запутывает.

Если вы под созданием объекта подразумеваете определение его в качестве члена другого класса, то, конечно, он должен быть определен в месте объявления класса, то есть в соответствующем .h файле.
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 13:35  [ТС]     Где создавать объекты классов? #3
То есть вот так сделать? Объявить объект в *.h - файле родного класса?

// Test.h
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
 
class CTest {
 
  public:
 
      void display ()
        { std::cout << "Hello" << std::endl; }
};
// Test.cpp
C++
1
2
3
4
5
6
#include "Test.h"
 
CTest obj;
 
void CTest::display ()
        { std::cout << "Hello" << std::endl; }
main.cpp
C++
1
2
3
4
5
6
7
8
#include "Test.h"
 
int main(int argc, char** argv) {
 
    obj.display();     // Error: Идентификатор obj не определен
 
    return 0;
}
Но тогда как в функции main обратиться через созданный объект к функции display()?
StasGamilton
Эксперт по пяченькам
 Аватар для StasGamilton
67 / 67 / 1
Регистрация: 16.08.2011
Сообщений: 258
18.04.2013, 13:41     Где создавать объекты классов? #4
Класс - тип данных, а объекты - это переменные.
Для себя я определяю int так:
C++
1
int abc; // int - класс, abc - объект
Так что, создание объектов классов и переменных основных типов подчинены одному и тому же закону.
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 13:45     Где создавать объекты классов? #5
Цитата Сообщение от dimkaok Посмотреть сообщение
Но тогда как в функции main обратиться через созданный объект к функции display()?
Значит, я вас неправильно понял.

Нет, в таком случае создавать объекты нужно в месте их использования.
C++
1
2
3
4
5
6
7
8
#include "Test.h"
 
int main(int argc, char** argv) {
    CTest obj;
    obj.display();
 
    return 0;
}
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 13:57  [ТС]     Где создавать объекты классов? #6
А можно объявить один и тот-же объект определенного класса в разных файлах несколько раз?
Или если определили объект obj класса A, то больше этого делать в программе нельзя?
StasGamilton
Эксперт по пяченькам
 Аватар для StasGamilton
67 / 67 / 1
Регистрация: 16.08.2011
Сообщений: 258
18.04.2013, 14:03     Где создавать объекты классов? #7
Цитата Сообщение от dimkaok Посмотреть сообщение
А можно объявить один и тот-же объект определенного класса в разных файлах несколько раз?
В смысле одного и того же имени? Опять, такая же ситуация, как и с обычными типами данных. Если в одной области видимости, но разные наименования, в разных областях видимости - можно повторять наименования.
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 14:12     Где создавать объекты классов? #8
Цитата Сообщение от dimkaok Посмотреть сообщение
А можно объявить один и тот-же объект определенного класса в разных файлах несколько раз?
Или если определили объект obj класса A, то больше этого делать в программе нельзя?
Да, если сделать объект глобальным и объявить с директивой extern. Например:

C++
1
2
3
4
5
// Test.h
 
class CTest { ... }; // пропущу объявление для краткости
 
extern CTest obj; // объявление общей переменной
C++
1
2
3
4
5
// Test.cpp
// определение методов класса
void CTest::display () { ... }
 
CTest obj; // определение, обязательно в cpp
Теперь объект obj можно использовать в разных cpp файлах, подключая Test.h:
C++
1
2
3
4
#include "Test.h"
void foo() {
  obj.display();
}
Однако сразу хочу предупредить, что использование глобальных данных приводит к плохой и немасштабируемой архитектуре. Избегайте их.
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 14:36  [ТС]     Где создавать объекты классов? #9
Ага, вроде понял. А еще такой вопрос:

У меня были объекты объявлены в *.cpp - файлах, я перенес объявления в *.h - файлы,
вроде ошибок не выдает. Правильно-ли, что я поместил объявление объектов в public - часть класса?

Добавлено через 5 минут
И еще, как я понял, если я объявил объект в классе А, а он (объект) мне понадобится
в классе В, то в классе В мне просто нужно будет подключить хеадер класса А?
StasGamilton
Эксперт по пяченькам
 Аватар для StasGamilton
67 / 67 / 1
Регистрация: 16.08.2011
Сообщений: 258
18.04.2013, 14:40     Где создавать объекты классов? #10
Цитата Сообщение от dimkaok Посмотреть сообщение
Правильно-ли, что я поместил объявление объектов в public - часть класса?
Все зависит от логики использования класса. Если объекты относяться к реализации класса, а из-вне они не используются, то в protected или в private. Но даже если они и используются, на мой взгляд необходимо сделать геттер и сеттер (функция возвращающая поле класса и устанавливающая его).
Кликните здесь для просмотра всего текста
Еще раз - также как и с переменными


Добавлено через 1 минуту
Цитата Сообщение от dimkaok Посмотреть сообщение
И еще, как я понял, если я объявил объект в классе А, а он (объект) мне понадобится
в классе В, то в классе В мне просто нужно будет подключить хеадер класса А?
Вы под объектом подразумеваете один объект? или два объекта одного и того же класса?
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 14:40     Где создавать объекты классов? #11
Цитата Сообщение от dimkaok Посмотреть сообщение
Правильно-ли, что я поместил объявление объектов в public - часть класса?
Похоже мы снова говорим немного на разных языках. Давайте определимся так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Test.h
 
// ниже [B]объявление[/B] класса
class CTest {
public:
  void foo();
 
private:
  int data_; // [B]определение[/B] члена класса
};
 
extern CTest obj; // [B]объявление[/B] объекта класса
 
...
// Test.cpp
 
void CTest::foo() {} // [B]определение[/B] метода класса
 
CTest obj; // [B]определение[/B] объекта класса
Итак, если речь про члены класса, их лучше определять в private-секции.
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 14:49  [ТС]     Где создавать объекты классов? #12
Цитата Сообщение от StasGamilton Посмотреть сообщение
Еще раз - также как и с переменными
Все никак в голове не увяжется Даже не думал, что для объектов, как и для переменных используются геттеры и сеттеры

Цитата Сообщение от StasGamilton Посмотреть сообщение
Вы под объектом подразумеваете один объект? или два объекта одного и того же класса?
Да, если я использую один единственный объект

Цитата Сообщение от shuffle Посмотреть сообщение
если речь про члены класса, их лучше определять в private-секции.
Ненене, я имею ввиду объявление объекта класса, как здесь: extern CTest obj;
Здесь он объявлен за пределами класса, а у меня объявлен внутри класса в public - части,
чтоб его другие классы могли использовать, и работает. Правильно внутри класса объявлять, или
за его пределами?
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 14:54     Где создавать объекты классов? #13
Цитата Сообщение от dimkaok Посмотреть сообщение
Правильно внутри класса объявлять, или
за его пределами?
Внутри класса, безусловно, лучше, чем глобальное определение. А делать ли член класса public или private или protected — второстепенный вопрос. Общая рекомендация — чем более закрытая область используется, тем лучше. Если вам не нужны наследники, указываетй private секцию и для доступа напишите геттер (сеттер, если необходимо), как указывали выше.
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 17:14  [ТС]     Где создавать объекты классов? #14
Ага, понял, спасибо. А то у меня в коде каша полная
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 17:22     Где создавать объекты классов? #15
Цитата Сообщение от dimkaok Посмотреть сообщение
Здравствуйте. Подскажите, если есть много классов, объявленных в заголовочных файлах,
а определенных в *.cpp - файлах, и для каждого класса создается объект, где эти объекты правильно создавать.
Я создаю их там где они оказываются нужны в первый раз. Например:
Нет. Если первый раз тебе объект понадобился в функции и ты там его создал, то в другой функции объекта не будет. Он нужен в единственном месте? Тогда ты поступил правильно. Нет? Ну значит нет. Не в том дело, где объект нужен первый раз, а где он вообще нужен. В принципе. В той области видимости и создавай.

Добавлено через 2 минуты
Цитата Сообщение от dimkaok Посмотреть сообщение
Правильно-ли, что я поместил объявление объектов в public - часть класса?
Объект нельзя разместить внутри его класса, рекурсия типов запрещена, исключение сделано только для указателей.

Добавлено через 1 минуту
Цитата Сообщение от dimkaok Посмотреть сообщение
И еще, как я понял, если я объявил объект в классе А, а он (объект) мне понадобится
в классе В, то в классе В мне просто нужно будет подключить хеадер класса А?
Нет. Головы инкладятся к файлам, но не к классам. И объект не может быть частью своего класса.

Добавлено через 44 секунды
Цитата Сообщение от StasGamilton Посмотреть сообщение
Все зависит от логики использования класса. Если объекты относяться к реализации класса, а из-вне они не используются, то в protected или в private. Но даже если они и используются, на мой взгляд необходимо сделать геттер и сеттер (функция возвращающая поле класса и устанавливающая его).
Ещё один такой же.
StasGamilton
18.04.2013, 17:31
  #16

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
Ещё один такой же.
Непонял. Это в каком смылсе?

taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 17:32     Где создавать объекты классов? #17
C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
};
 
A a; // объект класса A
class B
{
 A ba; // объект класса A, но член класса B. Такой объект называется агрегированным. Так следует делать тогда и только тогда, когда объект одного класса является частью объекта другого класса
};
 
B b; // Объект класса B, содержащий агрегированный объект ba класса A. Сам b - агрегат.
Цитата Сообщение от shuffle Посмотреть сообщение
Общая рекомендация — чем более закрытая область используется, тем лучше. Е
Бредятина. Если ты создал объект в закрытой области, а потом одумался и решил, что он нужен за её пределами, то придётся переделывать. И не один раз, а сотни. Любая переменная и объект в том числе должен быть объявлен в той области видимости, где он может быть нужен, не ниже, но и не выше даже на один уровень. И реально создан не раньше и не позже, чем это на самом деле нужно.
dimkaok
 Аватар для dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 17:44  [ТС]     Где создавать объекты классов? #18
Цитата Сообщение от taras atavin Посмотреть сообщение
Объект нельзя разместить внутри его класса, рекурсия типов запрещена, исключение сделано только для указателей.
Да не, я имел ввиду не внутри своего класса, а внутри класса, в котором этот объект вызывается.

А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 17:51     Где создавать объекты классов? #19
Цитата Сообщение от taras atavin Посмотреть сообщение
Если ты создал объект в закрытой области, а потом одумался и решил, что он нужен за её пределами, то придётся переделывать.
Или не переделывать, а предоставить к нему интерфейс доступа. Заменить private на public — вопрос 5 символов. Обратную замену сделать уже не так просто — придется рефакторить все места, где используется этот закрытый член (как вы и сказали, «не один раз, а сотни»). Чем меньше данных в открытом интерфейсе, тем меньше потенциальная связность объектов, тем более гибкая и автономная структура программы. Отсюда и рекомендация.

Добавлено через 2 минуты
Цитата Сообщение от dimkaok Посмотреть сообщение
А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
Да, это один из принципов ООП — инкапсуляция.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.04.2013, 19:07     Где создавать объекты классов?
Еще ссылки по теме:

Считается ли хорошим тоном создавать объекты классов в области глобальных переменных C++
Указатель на объекты и члены классов C++
C++ Не получается создать объекты шаблонных классов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 19:07     Где создавать объекты классов? #20
Цитата Сообщение от shuffle Посмотреть сообщение
Или не переделывать, а предоставить к нему интерфейс доступа. Заменить private на public — вопрос 5 символов.
И? Дело не в том, что к нему нельзя достучаться, а в том, что потом ты запутаешься, что у тебя где валяется. Потому что не понимаешь, где оно должно лежать, а можешь только слушать на эту тему чужие советы. И public работает только с классами. А если ты умудрился в функцию объект запихать? Хорошо, если обоснованно, тогда ни в коем случае не вытаскивай, противоположная ошибка так же плоха. А если сдуру?

Добавлено через 9 минут
Цитата Сообщение от dimkaok Посмотреть сообщение
Да не, я имел ввиду не внутри своего класса, а внутри класса, в котором этот объект вызывается.
А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
Агрегировать можно куда угодно, а часто агрегированные объекты и должны быть приватными. Думать надо, когда декларируешь и когда фактически создаёшь объекты. Думать и проектировать. Да и вообще при программировании. И решать в каждом конкретном случае, стоит ли прятать объект внутри другого класса. Часто стоит, а наследование не всегда уместно. Но вытекать этот приват должен из конкретных потребностей задачи, а не из абстрактнейших рекомендаций из всех возможных.
Цитата Сообщение от shuffle Посмотреть сообщение
придется рефакторить все места, где используется этот закрытый член (как вы и сказали, «не один раз, а сотни»).
Я имел ввиду совсем не это. 1 000 000 исправлений по всей проге в связи с изменнием видимости - это одна большая переделка. А вот передумать ещё раз и снова прятать то, что только что вытащил - это ещё большая глупость. Но когда исходишь только из посторонних советов на все случаи жизни, то передумывать можешь каждую минуту до срока сдачи и в итоге все завалить.

Добавлено через 9 минут
Цитата Сообщение от shuffle Посмотреть сообщение
Заменить private на public — вопрос 5 символов. Обратную замену сделать уже не так просто — придется рефакторить все места, где используется этот закрытый член (как вы и сказали, «не один раз, а сотни»). Чем меньше данных в открытом интерфейсе, тем меньше потенциальная связность объектов, тем более гибкая и автономная структура программы. Отсюда и рекомендация.
Проблема таких отвлечённых рекомендаций в том, что всегда найдётся псих, который посоветует всё в глобал вытащить и "обоснует" это тем, что всего лишь один объект не является частью другого. Мне не надо и 1 символ исправлять из-за областей видимости, не смотря на то, что хватает объектов в глобале с пабликом на все члены.
Yandex
Объявления
18.04.2013, 19:07     Где создавать объекты классов?
Ответ Создать тему
Опции темы

Текущее время: 20:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru