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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
Spice
4 / 4 / 0
Регистрация: 14.07.2008
Сообщений: 39
#1

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

19.08.2011, 13:53. Просмотров 1246. Ответов 9
Метки нет (Все метки)

Приветствую, Форумчане!

Следующий код, оформленный в одном файле работает на ура.
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 функции - на сколько должна быть маленькая функция, чтоб она подошла под inline? - C++
Здравствуйте. Знаю теорию, но не понимаю, на сколько должна быть маленькая функция, чтоб она подошла под inline ? Как...

inline функции vs инструкции inline функций - C++
Здравствуйте. Чтобы не писать повторно код, нужно использовать функции. Но если функции компактные, то их лучше делать inline функциями, т....

Не могу сделать чтобы класс содержал основной конструктор и конструктор копирования - C++
Разработать класс ThreeAngle для работы с плоскими треугольниками. В качестве членов-данных задаются длины трех сторон треугольника. Класс...

this(Всегда ли вызывается конструктор при не явной передачи объекта в конструктор) - C++
class Test { int i; public: void test(int i) { this -> i = i; } }; Конструктор Test::Test всегда вызывается...

Будет ли определен компилятором конструктор по умолчанию, если есть конструктор с дефолтным параметром? - C++
Добрый день, сразу к делу, есть некий класс class some { int x; public: some(int y = 1) : x(y) {} };

Создать класс. Написать конструктор по умолчанию, конструктор с параметрами. Перегрузить операции «меньше» и «равно» - C++
Помогите пожалуйста, хоть с одним из заданий. 1. Создать класс. Написать конструктор по умолчанию, конструктор с параметрами....

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
19.08.2011, 13:58 #2
правильно ругается. Мало просто заголовок подцепить. Надо еще cpp-сник откомпилировать.
Kastaneda
Форумчанин
Эксперт С++
4652 / 2860 / 228
Регистрация: 12.12.2009
Сообщений: 7,268
Записей в блоге: 2
Завершенные тесты: 1
19.08.2011, 14:14 #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
Эксперт С++
1040 / 819 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
19.08.2011, 14:15 #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 #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  [ТС] #7
Цитата Сообщение от villu
правильно ругается. Мало просто заголовок подцепить. Надо еще cpp-сник откомпилировать.
Что вы имеете ввиду?

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

Цитата Сообщение от Gera777
Потому что определение inline-функции должно быть доступно в той же единице трансляции, где используется.
Спасибо. По ходу дела это точный ответ на мой вопрос.
Есть ли более элегантное решение этой задачи?
Сыроежка
Заблокирован
19.08.2011, 21:26 #8
У вас совершенно некорректный код! Конструктор не может иметь спецификатор static Уберите ключевое слово static из объявления ваших конструкторов класса Point2.
Kastaneda
Форумчанин
Эксперт С++
4652 / 2860 / 228
Регистрация: 12.12.2009
Сообщений: 7,268
Записей в блоге: 2
Завершенные тесты: 1
19.08.2011, 21:31 #9
Цитата Сообщение от Сыроежка Посмотреть сообщение
У вас совершенно некорректный код! Конструктор не может иметь спецификатор static Уберите ключевое слово static из объявления ваших конструкторов класса Point2.
???
Сыроежка, нужно хотя бы внимательно посмотреть на код, перед тем как его критиковать!
Spice
4 / 4 / 0
Регистрация: 14.07.2008
Сообщений: 39
20.08.2011, 12:15  [ТС] #10
Спасибо всем за участие.
Gera777 ответил на мой вопрос.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2011, 12:15
Привет! Вот еще темы с ответами:

Не могу правильно сделать конструктор и конструктор копирования и принадлежность точки с заданными координатами треугольнику - C++
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; #include &lt;windows.h&gt; #include &lt;math.h&gt; #include &lt;algorithm&gt; using...

Можно ли использовать конструктор по умолчанию и конструктор инициализации одновременно? - C++
Можно ли использовать конструктор по умолчанию и конструктор инициализации одновременно?

Конструктор производного класса требует конструктор предка - C++
Выдаёт вот такую вот ошибку: no matching function for call to 'Cube::Cube()' class Cube { protected: int magInt; bool...

Конструктор инициализации, конструктор копирования, деструктор - C++
Я сделал почти задание по перегрузке операторов. Осталось одно, тоесть три: конструктор инициализации, конструктор копирования, деструктор....


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
20.08.2011, 12:15
Ответ Создать тему
Опции темы

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