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

Именованный конструктор + inline - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Spice
4 / 4 / 0
Регистрация: 14.07.2008
Сообщений: 39
19.08.2011, 13:53     Именованный конструктор + inline #1
Приветствую, Форумчане!

Следующий код, оформленный в одном файле работает на ура.
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
28
class Point2
{
public:
    static Point2 Decar(double dX, double dY);
    static Point2 Polar(double angle, double radius);
private:
    double dX;
    double dY;
    Point2(double dX, double dY);
};
 
inline Point2::Point2(double dX, double dY): dX(dX), dY(dY)
{
}
inline Point2 Point2::Decar(double dX, double dY)
{
    return Point2(dX, dY);
}
inline Point2 Point2::Polar(double angle, double radius)
{
    return Point2(radius * cos(angle), radius * sin(angle));
}
 
void main()
{
    Point2 point2 = Point2::Decar(1, 2);
    return;
}
Если же объявление класса вынести в отдельный заголовочный файл,
C++
1
2
3
4
5
6
7
8
9
10
11
12
class Point2
{
public:
    static Point2 Decar(double dX, double dY);
    static Point2 Polar(double angle, double radius);
 
private:
    double dX;
    double dY;
 
    Point2(double dX, double dY);
};
а определение в отдельный cpp файл,
C++
1
2
3
4
5
6
7
8
9
10
11
inline Point2::Point2(double dX, double dY): dX(dX), dY(dY)
{
}
Point2 Point2::Decar(double dX, double dY)
{
    return Point2(dX, dY);
}
Point2 Point2::Polar(double angle, double radius)
{
    return Point2(radius * cos(angle), radius * sin(angle));
}
и затем проинклудить заголовочный файл, то линкер начинает ругаться на следующий код:
C++
1
2
3
4
5
void main()
{
    Point2 point2 = Point2::Decar(1, 2);
    return;
}
Error 1 error LNK2019: unresolved external symbol "public: static class Point2 __cdecl Point2:ecar(double,double)" (?Decar@Point2@@SA?AV1@NN@Z) referenced in function _main E:\Coding\C++\Win32\Named Constructor Idiom\MainUnit.obj

Отказ от спецификатора inline решает вопрос, но так и не дает понять причину такого поведения.
У кого-нибудь есть вразумительное объяснение?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2011, 13:53     Именованный конструктор + inline
Посмотрите здесь:

C++ inline функции vs инструкции inline функций
this(Всегда ли вызывается конструктор при не явной передачи объекта в конструктор) C++
C++ Не могу сделать чтобы класс содержал основной конструктор и конструктор копирования
C++ Не могу правильно сделать конструктор и конструктор копирования и принадлежность точки с заданными координатами треугольнику
C++ Конструктор производного класса требует конструктор предка
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
19.08.2011, 13:58     Именованный конструктор + inline #2
правильно ругается. Мало просто заголовок подцепить. Надо еще cpp-сник откомпилировать.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
19.08.2011, 14:14     Именованный конструктор + inline #3
Цитата Сообщение от http://www.parashift.com/c++-faq/inline-functions.html
How do you tell the compiler to make a member function inline?

When you declare an inline member function, it looks just like a normal member function:

C++
1
2
3
4
class Fred {
  public:
    void f(int i, char c);
  };
But when you define an inline member function, you prepend the member function's definition with the keyword inline, and you put the definition into a header file:

C++
1
2
3
4
5
 inline
  void Fred::f(int i, char c)
  {
    ...
  }
It's usually imperative that the function's definition (the part between the {...}) be placed in a header file. If you put the inline function's definition into a .cpp file, and if it is called from some other .cpp file, you'll get an "unresolved external" error from the linker.
На сколько я понял со своим плохим английским, в твоем случае inline члены нужно определять в заголовочном файле, а не в cpp.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
19.08.2011, 14:15     Именованный конструктор + inline #4
Цитата Сообщение от villu Посмотреть сообщение
правильно ругается. Мало просто заголовок подцепить. Надо еще cpp-сник откомпилировать.
Ну так inline-функции имеют внутренне связывание... Грубо говоря, видны только в том файле, ГДЕ ОПРЕДЕЛЕНЫ.
Можно поставить extern перед inline - тогда будет видно везде.
Kastaneda
19.08.2011, 14:20
  #5

Не по теме:

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Ну так inline-функции имеют внутренне связывание...
Вот блин, сказывается то, что всегда делаю ф-ции inline'овыми путем определения их внутри класса, поэтому уже забыл про этот момент, пришлось вот гуглить)

Gera777
4 / 4 / 1
Регистрация: 09.07.2010
Сообщений: 12
19.08.2011, 14:34     Именованный конструктор + inline #6
Потому что определение inline-функции должно быть доступно в той же единице трансляции, где используется.
Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "stdafx.h"
#include <iostream>
#include "point2_inline.inl"
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    Point2 x = Point2::Decar(1,2);
    Point2 y = Point2::Polar(1,2);
 
    cin.get();
 
    return 0;
}
point2.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef _POINT2_H
#define _POINT2_H
 
class Point2
{
public:
    static Point2 Decar(double dX, double dY);
    static Point2 Polar(double angle, double radius);
 
private:
    double dX;
    double dY;
 
    Point2(double dX, double dY);
};
 
#endif
point2.inl
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <math.h>
#include "point2.h"
 
inline Point2::Point2(double dX, double dY): dX(dX), dY(dY)
{
}
inline Point2 Point2::Decar(double dX, double dY)
{
    return Point2(dX, dY);
}
inline Point2 Point2::Polar(double angle, double radius)
{
    return Point2(radius * cos(angle), radius * sin(angle));
}
Spice
4 / 4 / 0
Регистрация: 14.07.2008
Сообщений: 39
19.08.2011, 19:41  [ТС]     Именованный конструктор + inline #7
Цитата Сообщение от villu
правильно ругается. Мало просто заголовок подцепить. Надо еще cpp-сник откомпилировать.
Что вы имеете ввиду?

Цитата Сообщение от ValeryLaptev
Можно поставить extern перед inline - тогда будет видно везде.
Не помогло.

Цитата Сообщение от Gera777
Потому что определение inline-функции должно быть доступно в той же единице трансляции, где используется.
Спасибо. По ходу дела это точный ответ на мой вопрос.
Есть ли более элегантное решение этой задачи?
Сыроежка
Заблокирован
19.08.2011, 21:26     Именованный конструктор + inline #8
У вас совершенно некорректный код! Конструктор не может иметь спецификатор static Уберите ключевое слово static из объявления ваших конструкторов класса Point2.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4237 / 2770 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
19.08.2011, 21:31     Именованный конструктор + inline #9
Цитата Сообщение от Сыроежка Посмотреть сообщение
У вас совершенно некорректный код! Конструктор не может иметь спецификатор static Уберите ключевое слово static из объявления ваших конструкторов класса Point2.
???
Сыроежка, нужно хотя бы внимательно посмотреть на код, перед тем как его критиковать!
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2011, 12:15     Именованный конструктор + inline
Еще ссылки по теме:

C++ Создать класс. Написать конструктор по умолчанию, конструктор с параметрами. Перегрузить операции «меньше» и «равно»
C++ Inline функции - на сколько должна быть маленькая функция, чтоб она подошла под inline?
C++ Будет ли определен компилятором конструктор по умолчанию, если есть конструктор с дефолтным параметром?

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

Или воспользуйтесь поиском по форуму:
Spice
4 / 4 / 0
Регистрация: 14.07.2008
Сообщений: 39
20.08.2011, 12:15  [ТС]     Именованный конструктор + inline #10
Спасибо всем за участие.
Gera777 ответил на мой вопрос.
Yandex
Объявления
20.08.2011, 12:15     Именованный конструктор + inline
Ответ Создать тему
Опции темы

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