Подключение классов
C++, Visual Studio 2013
Как правильно подключать классы, если имеется следующая структура: Файл Base.h:
class base<>;
Файл Child1.h:
#include "base.h" class Child : public base
Файл Child2.h:
#include "base.h" class Child2 : public base
Файл Main.h:
#include "Child.h" #include "Child2.h"
При таком включении получаю ошибку линковки: переопределение класса base
Отслеживать
28.5k 12 12 золотых знаков 58 58 серебряных знаков 118 118 бронзовых знаков
задан 13 апр 2016 в 10:44
73 1 1 серебряный знак 6 6 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Скорее всего, у вас в h файлах отсутствует защита от двойного включения. Самый простой способ — добавить #pragma once в самый верх каждого .h файла или сделать по старинке — завернуть в охранный «гуард»
#ifndef _FILENAME_H_ #define _FILENAME_H_ // тут код #endif
_FILENAME_H_ — должно быть уникально для каждого файла, поэтому, обычно оно совпадает с именем файла. Этот способ работает на практически всех доступных компиляторах с/с++. pragma once может не работать на старых компиляторах.
Отслеживать
ответ дан 13 апр 2016 в 10:49
112k 6 6 золотых знаков 93 93 серебряных знака 159 159 бронзовых знаков
на практически всех . встречали случаи, где не работало?
13 апр 2016 в 11:13
да, я пользовался c комилятором, в котором не было define. Просто не было. Компилятор был по хитрые контроллеры, сейчас даже не вспомню. Автор вопроса вряд ли столкнется с подобным, но мало чего .
13 апр 2016 в 12:00
В таком случае это не может называться c компилятором в полной мере. Это просто какая-то поделка. И кстати, вопрос ТС по c++ .
13 апр 2016 в 12:07
я вкурсе, что вопрос по с++. А подделкой приходилось пользоваться, так как другого не было. А писать код прям в кодах мне не хотелось. Правда потом был прикручен препроцессор и все работало так как хотелось (да, если сильно быть педантом, обработка #ifdef — это работа препроцессора, а не компилятора. И как следствие ниодин правильный компилятор не поддерживает. Но современные компиляторы это скрывают и делают препроцессирование самостоятельно).
13 апр 2016 в 12:12
Понятно, что это работа препроцессора, но препроцессорные директивы тем не менее описаны в Стандарте по языку. И я бы отнес это к базовой части того, что реализация должна уметь. Иначе можно придумать и компиляторы, которые, скажем, не имеют оператора if . Но назвать такое компилятором си, язык не поворачивается.
Как подключить класс c
Нередко различные классы и структуры оформляются в виде отдельных библиотек, которые компилируются в файлы dll и затем могут подключаться в другие проекты. Благодаря этому мы можем определить один и тот же функционал в виде библиотеки классов и подключать в различные проекты или передавать на использование другим разработчикам.
Создадим и подключим библиотеку классов.
Возьмем имеющийся проект консольного приложения C#, например, созданный в прошлых темах. В структуре проекта нажмем правой кнопкой на название решения и далее в появившемся контекстном меню выберем Add -> New Project. (Добавить новый проект):

Далее в списке шаблонов проекта найдем пункт Class Library :

Затем дадим новому проекту какое-нибудь название, например, MyLib:

После создания этого проекта в решение будет добавлен новый проект, в моем случае с названием MyLib:

По умолчанию новый проект имеет один пустой класс Class1 в файле Class1.cs. Мы можем этот файл удалить или переименовать, как нам больше нравится.
Например, переименуем файл Class1.cs в Person.cs, а класс Class1 в Person. Определим в классе Person простейший код:
namespace MyLib < public class Person < string name; public Person(string name) < this.name = name; >public void Print() => Console.WriteLine($"Name: "); > >

Теперь скомпилируем библиотеку классов. Для этого нажмем правой кнопкой на проект библиотеки классов и в контекстном меню выберем пункт Rebuild :

После компиляции библиотеки классов в папке проекта в каталоге bin/Debug/net6.0 мы сможем найти скомпилированный файл dll (MyLib.dll). Подключим его в основной проект. Для этого в основном проекте нажмем правой кнопкой на узел Dependencies и в контекстном меню выберем пункт Add Project Reference. :

Далее нам откроется окно для добавления библиотек. В этом окне выберем пункт Solution,который позволяет увидеть все библиотеки классов из проектов текущего решения, поставим отметку рядом с нашей библиотекой и нажмем на кнопку OK:

Если наша библиотека вдруг представляет файл dll, который не связан ни с каким проектом в нашем решении, то с помощью кнопки Browse мы можем найти местоположение файла dll и также его подключить.
После успешного подключения библиотеки в главном проекте изменим файл Program.cs , чтобы он использовал класс Person из библиотеки классов:
using MyLib; // подключение пространства имен из библиотеки классов Person tom = new("Tom"); tom.Print(); // Name: Tom
Как создать свой класс и подключить его в main?
я новичок,хотел поинтересоваться,когда люди пишут программу,они сначала главную функцию main пишут,а потом пишут классы и подключают к main через #include? Просто создавал простенький класс в Visual studio 2015 по книжке,который просто на консоль выводит,и пошли проблемы,то написано что мой класс.h не найден,или то что нужны явные указатели какие-то.Просто интересно,как это правильно делать.Заранее спасибо
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как подключить свой класс?
Есть основной файл с тремя кнопками который выполняет функции при нажатии. Эти функции описаны в.
Как к проекту подключить свой класс
Здравствуйте. Объясните мне не учёному, как в Windows Forms к проекту подключить свой класс. Уже.
Как подключить свой класс к своему проекту WindowsFormsApplication?
Здравствуйте, уважаемые форумчане. Проблема такая. Сконструирована форма с кнопками и прочими.
как создать свой класс, в Делфи?
как создать свой класс, в Делфи? а потом вызвать, например при открытии? begin if.
Wanna be serious
586 / 473 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
andrue_selen, Если не секрет, какую литературу используете? Обычно в книгах для начинающих классы даются после прохождения базисных тем, в которых идёт толкование тех самых
Сообщение от andrue_selen 
явные указатели какие-то.
Если вам так интересно, то вот реализация простейшего класса:
Файл Source.cpp
1 2 3 4 5 6 7 8 9 10 11
#include #include #include "Man.h" int main() { Man man = Man("No name", 0, 0.0); man.Input_data(); man.Show_data(); system("Pause"); return 0; }
Файл Man.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
#include #include #include "Man.h" Man::Man(std::string _Name, int _age, double _height) { Name = _Name; age = _age; height = _height; } void Man::Input_data() { std::cout "Enter name: "; std::cin >> Name; std::cout "Enter age of man: "; std::cin >> age; std::cout "Enter height: "; std::cin >> height; } void Man::Show_data() { std::cout "\nName: " Name "\nAge: " age "\nHeight: " height "\n"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#pragma once #ifndef MAN_H_ #define MAN_H_ #include class Man { // Скрытые поля private: std::string Name; int age; double height; // Здесь располагаются функции-методы работы с данными public: Man(std::string _Name, int _age, double _height); ~Man() {} void Input_data(); void Show_data(); }; #endif
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от Bespridelschic 
Скрытые поля
Нет такого. Есть данные-члены (data members), которые некоторые называют также «полями класса» (class fields).
Сообщение от Bespridelschic 
функции-методы
Нет такого. Есть функции-члены (function members), которые некоторые называют также «методами класса» (class methods).
Соответственно, в зависимости от доступа, члены класса могут быть закрытыми (private members) или открытыми (public members).
![]()
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
Сообщение от gru74ik 
закрытыми (private members) или открытыми (public members).
Или защищенными ( protected )
Сообщение от Bespridelschic 
1 2 3
#pragma once #ifndef MAN_H_ #define MAN_H_
![]()
![]()
5277 / 2364 / 342
Регистрация: 20.02.2013
Сообщений: 5,763
Записей в блоге: 20
Сообщение от Tulosba 
Или защищенными (protected)
Или защищенными, да. Благодарю за уточнение.
Wanna be serious
586 / 473 / 186
Регистрация: 31.07.2013
Сообщений: 1,693
Сообщение от gru74ik 
Нет такого. Есть данные-члены (data members), которые некоторые называют также «полями класса» (class fields).
Я имел ввиду поля класса, скрытые от пользователя.
Сообщение от gru74ik 
Нет такого. Есть функции-члены (function members), которые некоторые называют также «методами класса» (class methods).
Тут я имел ввиду, функции, позволяющие работать с полями.
Сообщение от Tulosba 
Читал по поводу использованию #pragma once и #ifndef / #endif вместе, на сколько я понял ничего плохого в принципе быть не может
P.S. По поводу терминологии обещаю подтянуться
Регистрация: 06.10.2015
Сообщений: 8
Дейтел,программирование на С++.Там есть небольшое введение в классы в главе 3
Регистрация: 03.11.2015
Сообщений: 30
Вот еще рабочий пример, корявый, но рабочий в VS2008
исполняемый matrik.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#include "stdafx.h" #include #include #include "time.h" #include #include using namespace std; class matrik //создаем класс с помощью ключевого слова class и имени Name_class { public: // это спецификатор класс, он позволяет видеть все что идет после его int mas[50][50], mas2[50][50],sum[50][50],pro[50][50]; int n,m,a,s; void set() //функция ввода кол-ва строк и столбцов { coutendl"Введите количество строк"endl; cin>>n; coutendl"Введите количество столбцов"endl; cin>>m; coutendl; } void get() // функция заполнения и вывода матрицы { for (int i = 0; i n; i++) { for (int j = 0; j m; j++) { mas[i][j]=rand()%10+1; } } for (int i = 0; i n; i++) { coutendl; for (int j = 0; j m; j++) { coutmas[i][j]ends; } } } void get2() // функция заполнения и вывода матрицы 2 { for (int i = 0; i n; i++) { for (int j = 0; j m; j++) { mas2[i][j]=rand()%10+2; } } for (int i = 0; i n; i++) { coutendl; for (int j = 0; j m; j++) { coutmas2[i][j]ends; } } } /* void poisk() // функция поиска по индексу cout cin>>a; cout cin>>s; cout for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (((a-1)==i)&&((s-1)==j)) cout <<"Выбранный элемент "<> > > >*/ void summ() // функция сложения матриц { coutendl"Результат сложения матриц: "endl; for (int i = 0; i n; i++) { for (int j = 0; j m; j++) { sum[i][j]=mas[i][j]+mas2[i][j]; } } for (int i = 0; i n; i++) { coutendl; for (int j = 0; j m; j++) { coutsum[i][j]ends; }} } void prois() // функция произведения матриц { coutendl"Результат умножения матриц: "endl; for (int i = 0; i n; i++) { for (int j = 0; j m; j++) { pro[i][j]=mas[i][j]*mas2[i][j]; } } for (int i = 0; i n; i++) { coutendl; for (int j = 0; j m; j++) { coutpro[i][j]ends; }} } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
// Laba2.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h" #include #include #include "time.h" #include #include #include "matrik.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { matrik m; // создание объекта класса, это обязательно setlocale(LC_ALL,"Russian"); srand((unsigned)time(NULL)); int c, b; m.set(); coutendl; menu: //system("cls"); coutendl"1. Вывести первую матрицу: "endl; coutendl"2. Вывести вторую матрицу: "endl; coutendl"3. Вывести результат сложения матриц: "endl; coutendl"4. Вывести результат произведения матриц: "endl; coutendl"0. Выход: "endl; cin>>c; if (c==1){ goto masss1; } else { if (c==2){ goto masss2; } else { if (c==3){ goto sssum; } else { if (c==4) { goto sam; } else { if (c==0) { goto end; } else { coutendl"Ошибка ввода, повторите ввод "endl; goto menu; }}}}} masss1: m.get(); coutendl; goto menu; masss2: m.get2(); coutendl; goto menu; sssum: m.summ(); coutendl; goto menu; sam: m.prois(); coutendl; goto menu; end: //getch(); return 0; }
создание класса в отдельном файле
В созданном проекте, можно добавить класс, в отдельном файле, который сгенерирует Visual Studio.
Правой кнопкой мыши выделите проект. Add. New Item.

Добавьте файл класса.

Visual Studio сгенерировало класс. Пространство имен соответствует имени проекта. При желании, его можно удалить. Так же можно изменить название класса.