С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
1

Разделение класса на интерфейс и реализацию (ошибка __thiscall)

25.03.2017, 12:50. Просмотров 530. Ответов 15

Всем хай!

Есть такой наипростейший класс (для примера):
C++
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
#include "stdafx.h"
#include <iostream>
 
using namespace std;
class Test
{
private:
    int n;
public:
    Test(int pn)    // параметрический конструктор
    {
        n = pn;
    }
    void PrintN(void)   // вывод на экран
    {
        cout << "Текущее значение n: " << n << endl;
    }
};
 
int main()
{
    setlocale(LC_ALL, "");  // руссификация консоли
    Test ob(12);    // создание экземпляра класса
    ob.PrintN();    // вывод на экран приватного данного
    cin.get();  // задержка программы
    return 0;
}
Моя задача разбить класс на файл *.h и файл реализации. Потом передать др.человеку интерфейс класса + откомпилированный файл реализации, чтобы он мог использовать этот класс в своих приложениях, но при этом не видел детали реализации класса.
Вот, что у меня получилось:
Файл Test.h (интерфейс класс):
C++
1
2
3
4
5
6
7
8
class Test
{
private:
    int n;
public:
    Test(int pn);   // параметрический конструктор
    void PrintN(void);  // вывод на экран
};
Файл реализации класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "stdafx.h"
#include <iostream>
#include "Test.h"   // подключили интерфейс класса
using std::cout;
using std::endl;
 
Test::Test(int pn)  // параметрический конструктор
{
    n = pn;
}
void Test::PrintN(void) // вывод на экран
{
    cout << "Текущее значение n: " << n << endl;
}
Функция main():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "stdafx.h"
#include <iostream>
#include "Test.h"   // подключили интерфейс класса
 
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "");  // руссификация консоли
    Test ob(12);    // создание экземпляра класса
    ob.PrintN();    // вывод на экран приватного данного
    cin.get();  // задержка программы
    return 0;
}
Пока все работает прекрасно и проблем нету! Проблемы начинаются, когда я передаю Test.h и откомпилированный объектный файл(Test.obj) на др. комп. Т е на другом ПК оказывается описание класса + объектный файл реализации. При попытке создать программу с использованием класса Test возникает такого рода ошибка:
C++
1
error LNK2019: ссылка на неразрешенный внешний символ "public: __thiscall....
Как с этим бороться? Пытался делать релиз компиляцию перед отправкой - не помогло!
Может где-то в свойствах что-то нужно прописать проекта?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.03.2017, 12:50
Ответы с готовыми решениями:

Разделение программы на интерфейс и реализацию
Добрый вечер! Проблема в следующем: Компилятор visual studio 2010. есть...

как лучше всего добавлять предопределенные изменяемые значения char в интерфейс и реализацию класса?
Есть несколько непонятных мне моментов связанных с тем как использовать char в...

как лучше всего добавлять предопределенные изменяемые значения массива char в интерфейс и реализацию класса?
Есть несколько непонятных мне моментов связанных с тем как использовать char в...

Интерфейс класса и ошибка "Unresolved external 'Interface::Read() '"
interface Interface { __int32 Read(); };...

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

15
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
25.03.2017, 14:28 2
Во-первых #pragma once или аналог надо использовать в h-файле. Во-вторых, ты должен сделать и передать библиотеку (lib), а не obj.
Сам проект у тебя должен быть правильно создан: сначала консольное выбираешь, а после ставишь переключатель на static library.
0
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
25.03.2017, 16:19  [ТС] 3
Цитата Сообщение от nmcf Посмотреть сообщение
Во-первых #pragma once или аналог надо использовать в h-файле. Во-вторых, ты должен сделать и передать библиотеку (lib), а не obj.
Сам проект у тебя должен быть правильно создан: сначала консольное выбираешь, а после ставишь переключатель на static library.
#pragma once прописывается не в билдере? У меня Visual Studio. Какой аналог для нее или такой же?
Если я выбираю галочку static library, то создается только проект без файлов исходного кода. Мне потом нужно будет ВРУЧНУЮ добавлять файл с ф-цией main?

Добавлено через 4 минуты
И можно ли сделать это БЕЗ использования static library?
А под C++ for DOS 3.1 тоже нужно было также через библиотеку? Там вроде передавался файл *.h и объектный (скомпилированный) файл?
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
25.03.2017, 16:33 4
Цитата Сообщение от FasterHarder Посмотреть сообщение
#pragma once прописывается не в билдере?
Для VS подходит.
Цитата Сообщение от FasterHarder Посмотреть сообщение
Мне потом нужно будет ВРУЧНУЮ добавлять файл с ф-цией main?
FasterHarder, ну какой ещё main? У тебя должно быть два файла: h и cpp, в первом заголовок класса, во втором - реализация.

Добавлено через 1 минуту
Цитата Сообщение от FasterHarder Посмотреть сообщение
А под C++ for DOS 3.1 тоже нужно было также через библиотеку?
Ты ещё graphics.h вспомни. Выбрось эту древность.
lib-файлы были и в DOS тоже. Это давно придумано.
0
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
25.03.2017, 17:08  [ТС] 5
Цитата Сообщение от nmcf Посмотреть сообщение
У тебя должно быть два файла: h и cpp, в первом заголовок класса, во втором - реализация.
Хорошо!
Но тут кое-что хочу понять еще. Когда создается консольное приложение в VS, то там в настройках можно задать тип приложения(windows, консольное, библиотека DLL, статическая библиотека). Как я понял, нужно выбирать СТАТИЧЕСКАЯ БИБЛИОТЕКА. Создается как бы ПУСТОЙ проект (нет ф-ции main). Затем я ВРУЧНУЮ добавляю файл *.cpp и там реализация класса. Затем ВРУЧНУЮ добаляю *.h и там интерфейс класса. Затем добавляю #pragma once(препроцессорная директива, разработанная для контроля за тем, чтобы конкретный исходный файл при компиляции подключался строго один раз). Нажимаю компиляцию. Класс готов к использованию на др.ПК.

Если захочу протестить библиотечку, то создаю НОВЫЙ проект (выбираю тип консольный) и уже там могу использовать эту lib.
Вопрос: файл *.lib должен быть в той же папке, что и исполняемый файл?

Цитата Сообщение от nmcf Посмотреть сообщение
Ты ещё graphics.h вспомни. Выбрось эту древность.
lib-файлы были и в DOS тоже. Это давно придумано.
На этой неделе сталкивался с графикой под ДОС)
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
25.03.2017, 17:25 6
Не вручную, а через Project - Add Item. Если там действительно ничего нет.
Цитата Сообщение от FasterHarder Посмотреть сообщение
Если захочу протестить библиотечку, то создаю НОВЫЙ проект
Да.
Цитата Сообщение от FasterHarder Посмотреть сообщение
файл *.lib должен быть в той же папке, что и исполняемый файл?
Нет, он либо в отдельной папке, и тогда надо настраивать пути компилятора, либо внутри проекта. Здесь надо проверять.
0
hoggy
Заблокирован
Эксперт С++
25.03.2017, 17:36 7
Цитата Сообщение от FasterHarder Посмотреть сообщение
Как с этим бороться?
как то так:

http://g.zeos.in/?q=%D1%81%2B%2B%20%...B5%D0%BA%D0%B0
1
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
25.03.2017, 17:41  [ТС] 8
Цитата Сообщение от nmcf Посмотреть сообщение
Нет, он либо в отдельной папке, и тогда надо настраивать пути компилятора, либо внутри проекта. Здесь надо проверять.
последние уточнения!
Проще настроить путь компилятора или ВНУТРЬ проекта?
Я вроде знаю, где в опциях задается путь компилятора для библиотек: проект-свойства-свойства конфигурации-каталоги VC++ - каталоги библиотек. Или это вообще НЕ ТО?
Внуть проекта - это В КОРЕНЬ проекта или в ДЕБАГ куда-нибудь или лучше прогнать все возможные случаи и там, где сработает, там и оставить?
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
25.03.2017, 18:55 9
Ну попробуй поместить и h и lib туда, где у тебя cpp, содержащий main(). А в сам cpp добавь
C++
1
#pragma comment (lib, "mylib.lib")
0
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
25.03.2017, 23:52  [ТС] 10
В общем все получилось!
Т е я передал на чужой ПК два файла (*.h, *.lib).
Там создался проект консольный. В опциях был прописан путь до директории, где лежит *.h.
Никакие *pragma не потребовались. Но была проблема с линковкой, т к ссылка на ЛИБУ не добавлялась в принципе. Поэтому пришлось ТУПО добавить в текущий проект "Существующий элемент" и выбрать эту *.lib. С кучей ворнингов все запустилось. Так нормально делать, да?

В любом случае nmcf спс. за помощь!
0
nmcf
6515 / 5744 / 2617
Регистрация: 14.04.2014
Сообщений: 24,494
25.03.2017, 23:59 11
Цитата Сообщение от FasterHarder Посмотреть сообщение
Никакие *pragma не потребовались. Но была проблема с линковкой
Вот для этого и надо #pragma добавлять.
0
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
26.03.2017, 00:04  [ТС] 12
Цитата Сообщение от nmcf Посмотреть сообщение
Вот для этого и надо #pragma добавлять.
хм...я вроде понял, зачем нужна ПРАГМА (ключевое слово ведать "вроде")
но почти уверен, что дело не в ней было... хотя хз)

Т е так, как я сделал - очень коряво или сойдет на 1-е время...
0
hoggy
Заблокирован
Эксперт С++
26.03.2017, 00:14 13
Цитата Сообщение от FasterHarder Посмотреть сообщение
Так нормально делать, да?
через жёпу. да
1
nd2
2838 / 2405 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
26.03.2017, 00:15 14
Цитата Сообщение от FasterHarder Посмотреть сообщение
Так нормально делать, да?
Нет.
Цитата Сообщение от FasterHarder Посмотреть сообщение
ссылка на ЛИБУ не добавлялась в принципе.
Куда не добавлялась?
Компоновщику нужно прописать путь до либы, и имя либы.
0
FasterHarder
4 / 2 / 1
Регистрация: 28.04.2015
Сообщений: 161
26.03.2017, 00:21  [ТС] 15
Цитата Сообщение от hoggy Посмотреть сообщение
через жёпу. да
я так и думал, но ведь работает!)

Цитата Сообщение от nd2 Посмотреть сообщение
Куда не добавлялась?
в опциях VS проекта: контекстное меню - ссылки - общий свойства - добавить новую ссылку и там ПУСТО и нет никакого эллипсиса для добавления чего-либо!

В общем ладно, как-нить разберусь...
0
nd2
2838 / 2405 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
26.03.2017, 00:29 16
Цитата Сообщение от FasterHarder Посмотреть сообщение
в опциях VS проекта: контекстное меню - ссылки - общий свойства - добавить новую ссылку и там ПУСТО и нет никакого эллипсиса для добавления чего-либо!
Добавляется в свойствах проекта. Компоновщик, Общие, Дополнительные каталоги библиотек: путь к папке с либой.
Компоновщик, ввод, дополнительные зависимости: имя либы.
0
26.03.2017, 00:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.03.2017, 00:29

Где размещать реализацию методов класса?
привет. читаю книжку по С++. автор Либерти. в ней куча опечаток повсюду....

Опять про реализацию класса в отдельном файле
Допустимо ли следующее? есть проект в Visual Studio 2010. в нем следующие...

Исправить реализацию friend-функции для шаблонного класса
Здравствуйте! Есть шаблонный класс, для которого нужно перегрузить операторы...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru