Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Линковка] Как обратиться к классу, определенному, в другом cpp-файле? 
V
    Опции темы
azesmcar
Дата 17.7.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22

Потому что в этом случае она инлайниться, а инлайн функции как известно должны быть объявлены во всех translation unit-ах.

Добавлено через 59 секунд
Цитата(Стандарт)

An inline function shall be defined in every translation unit in which it is used.

PM   Вверх
zim22
Дата 17.7.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  17.7.2009,  16:19 Найти цитируемый пост)
Потому что в этом случае она инлайниться, а инлайн функции как известно должны быть определены во всех translation unit-ах.

т.е. можно переопределять её тело, как это ни печально?
и во время объявления класса в main.cpp я изменил его члены данных (определил value типа int) - это тоже прокатило...
т.е. это уже два разных класса получается, а не один. хотя и не совсем два - т.к. конструктор у них один - общий...
ужас какой-то получается

Код

class A {
public:
  A(); 
  void fcn() { int x = 5; }
  int value;  
};

int main()
{  
   A t;
   t.fcn();   
   t.value = 20;

  return 0;
}


Код

// A.cpp
class A
{
public:
  A();
  void fcn(){int y = 10; }
private:
  int data;
};

A::A() : data(99) { }




Это сообщение отредактировал(а) zim22 - 17.7.2009, 16:31


--------------------
PM MAIL   Вверх
azesmcar
Дата 17.7.2009, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(zim22 @  17.7.2009,  16:30 Найти цитируемый пост)
определены 

точно smile опять эти слова спутал

Цитата(zim22 @  17.7.2009,  16:30 Найти цитируемый пост)
ужас какой-то получается

а вот насчет этого ужаса
Цитата

An inline function shall be defined in every translation unit in which it is used and shall have exactly the
same definition in every case 
(3.2).

так что то, что это безобразие работает где-то еще ничего не значит smile
PM   Вверх
zim22
Дата 17.7.2009, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



ок. с inline функциями разобрался  smile 
как насчёт этого:
Цитата(zim22 @  17.7.2009,  16:30 Найти цитируемый пост)
и во время объявления класса в main.cpp я изменил его члены данных (определил value типа int) - это тоже прокатило...т.е. это уже два разных класса получается, а не один. хотя и не совсем два - т.к. конструктор у них один - общий...




--------------------
PM MAIL   Вверх
azesmcar
Дата 17.7.2009, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22

Ну на С++ есть множество способов извратиться, потому этот язык и считается сложным и именно потому для него написано столько книг. Просто не надо так извращаться smile 
PM   Вверх
Леопольд
Дата 17.7.2009, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Вот это тоже работает, в VC 2008 Express, а не должно:

test.cpp
Код

#include <iostream>

struct S{
private:
    int value;
public:
    S(void);
    int fnc(void){
        return value;
    }
    void mem_fun(void);
};

S::S(void):value(5) {}

void S::mem_fun(void){
    std::cout<<fnc()<<std::endl;
}


main.cpp
Код

class S{
    int value;
public:
    S(void);
    int fnc(void){
        return 10;
    }
    void mem_fun(void);
};


int main(int argc, char* argv[])
{
    S().mem_fun();
    return 0;
}


Но при этом выводит 5 в консольке. Не удивлюсь, если g++ откажется это собирать... Не удивлюсь, если соберёт, и выведет 10 smile или 5  smile 

Это сообщение отредактировал(а) Леопольд - 17.7.2009, 17:07


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
zim22
Дата 17.7.2009, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Леопольд @  17.7.2009,  17:03 Найти цитируемый пост)
Вот это тоже работает, в VC 2008 Express:

а почему бы ему и не работать. как по мне - обычный код smile
Цитата(Леопольд @  17.7.2009,  17:03 Найти цитируемый пост)
Но при этом выводит 5 в консольке.

он и должен 5 выводить. по крайней мере я в уме пошагово прошёл - 5 на выходе оказалось smile
Код

int main(int argc, char* argv[])
{
    S obj; // конструктор инициализирует value "пятёркой"
    obj.mem_fun(); // вызывается функция mem_fun из test.cpp. 
                            // она выводит value на экран. а оно равно пяти.
    return 0;
}


Это сообщение отредактировал(а) zim22 - 17.7.2009, 17:09


--------------------
PM MAIL   Вверх
Леопольд
Дата 17.7.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Цитата(zim22 @ 17.7.2009,  17:08)
Цитата(Леопольд @  17.7.2009,  17:03 Найти цитируемый пост)
Вот это тоже работает, в VC 2008 Express:

а почему бы ему и не работать. как по мне - обычный код smile

По стандарту, это не должно скомпилироваться.


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
zim22
Дата 17.7.2009, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Леопольд @  17.7.2009,  17:03 Найти цитируемый пост)
Не удивлюсь, если g++ откажется это собирать... 

собирает. без единого warning'a
Цитата(Леопольд @  17.7.2009,  17:10 Найти цитируемый пост)
По стандарту, это не должно скомпилироваться.

ссылочкой не поделитесь где это в стандарте?
***
приведенные вами два cpp файла аналогичны нижеизложенному коду, за одним исключением, в котором вы сами нарушили стандарт:
переопределили тело инлайн функции.

Код

#include "test.h"

int main()
{
  S().mem_fun();
  return 0;
}

Код

// test.h
#ifndef TEST_H
#define TEST_H

struct S{
private:
    int value;
public:
    S(void);
    int fnc(void){
        return value;
    }
    void mem_fun(void);
};


#endif // TEST_H

Код

// test.cpp
#include "test.h"
#include <iostream>

S::S(void):value(5) {}

void S::mem_fun(void){
    std::cout<<fnc()<<std::endl;
}



Это сообщение отредактировал(а) zim22 - 17.7.2009, 17:21


--------------------
PM MAIL   Вверх
Леопольд
Дата 17.7.2009, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Цитата(zim22 @ 17.7.2009,  17:14)
ссылочкой не поделитесь где это в стандарте?

azesmcar уже цитировал стандарт

Попробуйте заменить main вот на это smile

Код

int main(int argc, char* argv[])
{
    S obj;
    obj.mem_fun();
    std::cout<<obj.fnc()<<std::endl;
    return 0;
}


А потом на это
Код

int main(int argc, char* argv[])
{
    S obj;
    obj.mem_fun();
//  std::cout<<obj.fnc()<<std::endl;
    return 0;
}


надо будет добавить в main #include <iostream>

Это сообщение отредактировал(а) Леопольд - 17.7.2009, 17:25


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
zim22
Дата 17.7.2009, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Леопольд @  17.7.2009,  17:20 Найти цитируемый пост)
azesmcar уже цитировал стандарт

прочитайте ещё раз то, что он цитировал
Цитата(azesmcar @  17.7.2009,  16:37 Найти цитируемый пост)
An inline function shall be defined in every translation unit in which it is used and shall have exactly thesame definition in every case (3.2).

shall != must


--------------------
PM MAIL   Вверх
Леопольд
Дата 17.7.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Цитата(zim22 @ 17.7.2009,  17:23)
shall != must

Однако ворнинга нет...  А значит, компилятор забил на этот shall smile Я думаю, это бага в gcc 4.3.3

Добавлено @ 17:30
А вот это даёт разный результат в VC 2008 Express и в gcc 4.3.3 - компиляторам нельзя верить, надо проверять smile В этом случае, я думаю, они оба отсупили от стандарта. Даже ворнинга нет, хотя, по моему, это вообще не должно компилироваться. Остаётся только считать, то это даёт нам undefined behaviour.

Код

int main(int argc, char* argv[])
{
    S().mem_fun();
    std::cout<<S().fnc()<<std::endl;
    return 0;
}


Это сообщение отредактировал(а) Леопольд - 17.7.2009, 17:35


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
zim22
Дата 17.7.2009, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(Леопольд @  17.7.2009,  17:26 Найти цитируемый пост)
Однако ворнинга нет...  А значит, компилятор забил на этот shall

да, глюк неприятный. undefined behavior. однако избежать его достаточно просто - не переопределять inline функции smile


--------------------
PM MAIL   Вверх
Леопольд
Дата 17.7.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 3
Всего: 13



Цитата(zim22 @ 17.7.2009,  17:34)
да, глюк неприятный. undefined behavior. однако избежать его достаточно просто - не переопределять inline функции smile

По старинке, пользоваться #include  smile 


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
mes
Дата 17.7.2009, 20:17 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(zim22 @  17.7.2009,  14:53 Найти цитируемый пост)

ну а почему с функциями прокатывает? 

потому что Вы путаете сущности  этапа компиляции и линковки. Для начала исходный код, транслируется в объектный - этап компиляции.
На этом этапе Cpp-код  лишается всего своего ООП . В итоге объектники cpp, си, паскаля, асма и др. "выглядят" одинаково и из нескольких таких (полученных с разных языков) объектников можно слинковать одну общую прогу. 



--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1003 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.