Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
#1

Link error на inline функцию - C++

01.09.2010, 12:08. Просмотров 965. Ответов 9
Метки нет (Все метки)

Почему выдает ошибку [Linker error] undefined reference to `OldCat::GetAge() const'
на inline ф-цию при ее вызове?
Убираю inline, все компилится нормально.
Функция простая:

C++
1
2
3
4
5
inline int OldCat::GetAge() const
{
    cout << "Calling function GetAge..." << endl;
    return itsAge;
}

среда Dev-C++ v4.9.9.2 (на базе minGW, на сколько я понимаю)
компилятор gcc 3.4.2 (mingw-special)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.09.2010, 12:08
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Link error на inline функцию (C++):

Причина ошибки [ilink32 Error] Error: Unable to perform link - C++
Когда сохранил программу и пытаюсь открыть ее снова то мне выкидывает ошибку Warning: Error detected (LME288) Error: Unable to...

Как адаптировать функцию под inline - C++
Дана функция: bool Str(ifstream &amp;f, const char *s) { char buff; return !(f.get(buff,...

Inline функции - на сколько должна быть маленькая функция, чтоб она подошла под inline? - C++
Здравствуйте. Знаю теорию, но не понимаю, на сколько должна быть маленькая функция, чтоб она подошла под inline ? Как...

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

При вынесении определения всегда ли нужно указывать функцию как inline явно? - C++
Бьярни пишет class char_stack { int size; char* top; char* s; public: char_stack(int sz) { top=s=new char; } ...

Написать встроенную (inline) функцию, которая вычисляет абсолютное значение из аргумента типа float - C++
опять я туда же, и опять буду крайне благодарна за комментарии, чтоб я понимала что я делаю не так... ((

9
fasked
Эксперт С++
4963 / 2543 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
01.09.2010, 12:09 #2
inline напишите в прототипе.
0
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 12:12  [ТС] #3
разницы нет..
даже если в определении класса напрямую пишу:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class OldCat
{
    public:
        ...
        int GetAge() const
        {
            cout << "Calling function GetAge..." << endl;
            return itsAge;
        }
        ...
    private:
        int itsAge;
        ...
};
0
Nameless One
Эксперт С++
5780 / 3429 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
01.09.2010, 12:18 #4
nimoid, покажи весь код.
0
fasked
Эксперт С++
4963 / 2543 / 180
Регистрация: 07.10.2009
Сообщений: 4,311
Записей в блоге: 1
01.09.2010, 12:24 #5
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
#include <iostream>
 
class OldCat
{
public:
    inline void SetAge(int age);
    inline int GetAge() const;
private:
    int age;
};
 
void OldCat::SetAge(int age)
{
    this->age = age;
}
 
int OldCat::GetAge() const
{
    return age;
}
 
int main()
{
    OldCat cat;
 
    cat.SetAge(10);
    std::cout << cat.GetAge() << std::endl;
}
0
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 12:46  [ТС] #6
fasked, странно, в книжке у Либерти наоборот inline в реализации функции стоит, а не в объявлении класса.. Но, впрочем, так тоже ошибку выдает.

Полный код:

main.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "cats.h"
 
int main()
{
    OldCat * pPushok = new OldCat(7);
    
    pPushok->Meow();
    
    cout << pPushok->GetAge() << endl;
    
    delete pPushok;
    pPushok = NULL;
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
cats.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
using namespace std;
 
 
class OldCat
{
    public:
        OldCat(int age);
        OldCat(OldCat&);
        ~OldCat();
        int GetAge() const;
        void SetAge(int age);
        void Meow() const;
    private:
        int itsAge;
        int itsLapok;
};
cats.cpp

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
29
30
31
32
33
34
35
36
37
#include "cats.h"
 
 
OldCat::OldCat(int age)
{
    cout << "Calling constructor..." << endl;
    itsAge = age;
}
 
OldCat::~OldCat()
{
    cout << "Calling destructor..." << endl;
}
 
OldCat::OldCat(OldCat&)
{
    cout << "Calling copy constructor..." << endl;
}
 
 
inline int OldCat::GetAge() const
{
    cout << "Calling function GetAge..." << endl;
    return itsAge;
}
 
void OldCat::SetAge(int age)
{
    cout << "Calling function SetAge..." << endl;
    itsAge = age;
}
 
 
void OldCat::Meow() const
{
    cout << "Meeoooow!" << endl;
}
0
Nameless One
Эксперт С++
5780 / 3429 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
01.09.2010, 13:11 #7

Не по теме:

Открывать пространство имен в заголовочном файле - плохо.



Надо использовать для заголовочных файлов связку #ifndef-#define-#endif или, в крайнем случае, #pragma once

Теперь по теме: встроенные функции должны быть определены внутри заголовочного файла. Также рекомендуется ставить спецификатор inline у определения, а не у объявления метода.
Переделанная версия:
Cats.hpp:
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
29
#ifndef CATS_HPP
#define CATS_HPP
 
#include <iostream>
 
class OldCat
{
 
public:
 
    OldCat(int age);
    OldCat(const OldCat&);
    ~OldCat();
    int GetAge() const;
    void SetAge(int age);
    void Meow() const;
 
private:
 
    int itsAge;
};
 
inline int OldCat::GetAge() const
{
    std::cout << "Calling function GetAge..." << std::endl;
    return itsAge;
}
 
#endif // CATS_HPP
Cats.cpp:
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
29
30
#include "cats.hpp"
 
OldCat::OldCat(int age)
{
    std::cout << "Calling constructor..." << std::endl;
    itsAge = age;
}
 
OldCat::~OldCat()
{
    std::cout << "Calling destructor..." << std::endl;
}
 
OldCat::OldCat(const OldCat& rhs)
{
    std::cout << "Calling copy constructor..." << std::endl;
    itsAge = rhs.itsAge;
}
 
void OldCat::SetAge(int age)
{
    std::cout << "Calling function SetAge..." << std::endl;
    itsAge = age;
}
 
 
void OldCat::Meow() const
{
    std::cout << "Meeoooow!" << std::endl;
}
main.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cstdlib>
 
#include "cats.hpp"
 
int main()
{
    OldCat* pPushok = new OldCat(7);
    pPushok->Meow();
    std::cout << pPushok->GetAge() << std::endl;
    OldCat* pMursik = new OldCat(*pPushok);
    pMursik->SetAge(15);
    std::cout << pMursik->GetAge() << std::endl;
    delete pPushok;
    delete pMursik;
    pPushok = NULL;
    pMursik = NULL;
    return EXIT_SUCCESS;
}

Не по теме:

Поле itsLapok было неиспользовано, поэтому я его удалил

0
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 13:16  [ТС] #8
Цитата Сообщение от Nameless One Посмотреть сообщение

Не по теме:

Открывать пространство имен в заголовочном файле - плохо.



Надо использовать для заголовочных файлов связку #ifndef-#define-#endif или, в крайнем случае, #pragma once
1. А где пространство имен открывать?
2. Покажите пожалуйста пример #ifndef-#define-#endif , я еще до этого не дошел по ходу

Вообще лучше можете привести пример как правильно надо это все организовать (с такой структурой как у меня) с дефайнами и с пространствами имен? Если не сложно, конечно..

Добавлено через 46 секунд
о, спасибо, уже опередили )
0
Nameless One
Эксперт С++
5780 / 3429 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
01.09.2010, 13:29 #9
Цитата Сообщение от nimoid Посмотреть сообщение
А где пространство имен открывать?
Лучше его вообще не открывать, а явно уточнять используемое пространство имен перед идентификатором (например, std::cout)
Цитата Сообщение от nimoid Посмотреть сообщение
Покажите пожалуйста пример #ifndef-#define-#endif , я еще до этого не дошел по ходу
Тут нужно сделать небольшое отступление и рассказать, как производится обработка директивы include. Перед компиляцией программы препроцессор просматривает файлы и, когда натыкается на директиву #include, производит подстановку на место директивы всего содержимого файла, указанного в директиве (предварительно удалив комментарии и подставив #define'ы). Так вот, в крупных проектах может случиться так, что некоторые заголовочные файлы должны подключаться несколько раз (да и при использовании стандарной библиотеки, см. пример выше - iostream подключается в файле main.cpp и cats.hpp). Если не использовать связку #ifndef-#define-#endif, то получается, что препроцессор вставит содержимое заголовочного файла два (или больше) раза подряд, что будет ошибкой повторного определения классов, функций и т.д., описанных в этом заголовочном файле. А так во время первого подключения заголовочного файла происходит определение символа (#define CATS_HPP), которое заставляет препроцессор пропускать следующие подключения этого файла.
Вместо всего этого (#ifnef-#define-#endif) можно было бы один раз прописать в начале заголовочного файла #pragma once, но вся беда в том, что эта директива поддерживается не всеми компиляторами.

Можешь прочитать faq для окончательного просветления
1
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 13:40  [ТС] #10
Спасибо большое за разъяснения, все понял
0
01.09.2010, 13:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.09.2010, 13:40
Привет! Вот еще темы с ответами:

Ошибка (LINK : fatal error) - C++
VS 2010 Express: LINK : fatal error LNK1104: не удается открыть файл &quot;C:\Users\Администратор\documents\visual studio 2010\....exe&quot; При...

Error executing link.exe - C++
подскажите пожалуйста)

LINK : fatal error LNK1561: entry point must be defined - C++
Создан как Empty project Код программы: namespace program { void main() { } }

LINK: fatal error LNK1168: не удается открыть exe для записи - C++
Подскажите пожалуйста,что значит эта ошибка? 1&gt;------ Построение начато: проект: Курсовая лаба, Конфигурация: Debug Win32 ------ ...


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

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

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