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

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

Восстановить пароль Регистрация
 
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 12:08     Link error на inline функцию #1
Почему выдает ошибку [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)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fasked
Эксперт C++
 Аватар для fasked
4925 / 2505 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
01.09.2010, 12:09     Link error на inline функцию #2
inline напишите в прототипе.
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 12:12  [ТС]     Link error на inline функцию #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;
        ...
};
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
01.09.2010, 12:18     Link error на inline функцию #4
nimoid, покажи весь код.
fasked
Эксперт C++
 Аватар для fasked
4925 / 2505 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
01.09.2010, 12:24     Link error на inline функцию #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;
}
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 12:46  [ТС]     Link error на inline функцию #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;
}
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
01.09.2010, 13:11     Link error на inline функцию #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 было неиспользовано, поэтому я его удалил

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

Не по теме:

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



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

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

Добавлено через 46 секунд
о, спасибо, уже опередили )
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
01.09.2010, 13:29     Link error на inline функцию #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 для окончательного просветления
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.09.2010, 13:40     Link error на inline функцию
Еще ссылки по теме:

C++ Inline функции - на сколько должна быть маленькая функция, чтоб она подошла под inline?
При вынесении определения всегда ли нужно указывать функцию как inline явно? C++
C++ LINK: fatal error LNK1168: не удается открыть exe для записи

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

Или воспользуйтесь поиском по форуму:
nimoid
0 / 0 / 0
Регистрация: 01.09.2010
Сообщений: 14
01.09.2010, 13:40  [ТС]     Link error на inline функцию #10
Спасибо большое за разъяснения, все понял
Yandex
Объявления
01.09.2010, 13:40     Link error на inline функцию
Ответ Создать тему
Опции темы

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