inlining overloaded methods

T

t

If a method of a class is overloaded, and one of these methods is
inlined, do all of them have to be inlined?

I tried writing and filling out an example from Lippman's C++ book,
4th ed., and found that I had to inline all of the overloaded methods
to make the linking work. Lippman doesn't mention this, though.
 
A

Alf P. Steinbach

* t:
If a method of a class is overloaded, and one of these methods is
inlined, do all of them have to be inlined?
No.


I tried writing and filling out an example from Lippman's C++ book,
4th ed., and found that I had to inline all of the overloaded methods
to make the linking work. Lippman doesn't mention this, though.

Post example code.

Cheers, & hth.,

- Alf
 
T

t

I isolated a part of the code to quote for you, but found it you are
correct. The linking error I get is coming from a more complicated
situation that also involves a second class and a friend declaration.
Here is an abridged version (sorry I can't make it shorter):

==================================================================================

#ifndef SCREEN_H
#define SCREEN_H

#include <string>

// #include "Window_Mgr.h" // for 2nd version of program

class Screen
{
// for 2nd version of program
// friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index,
// Window_Mgr::index, Screen&);

friend class Window_Mgr;

public:
typedef std::string::size_type index;

char get() const
{ return contents_[cursor_]; }
char get(index r, index c) const;

private:
std::string contents_;
index cursor_;
index height_, width_;
};


// inline declared in the class declaration; no need to repeat on the
definition
char Screen::get(index r, index c) const
{
index row = r * width_; // compute the row location
return contents_[row + c]; // offset by c to fetch specified
character
}

#endif

==================================================================================

#ifndef WINDOW_MGR_H
#define WINDOW_MGR_H

#include <string>

class Screen;

class Window_Mgr
{
public:
typedef std::string::size_type index;

Window_Mgr& relocate(Window_Mgr::index, Window_Mgr::index, Screen&);

private:
};

#endif

==================================================================================

// Window_Mgr.cpp

#include "Window_Mgr.h"
#include "Screen.h"

Window_Mgr& Window_Mgr::relocate(Window_Mgr::index r,
Window_Mgr::index c, Screen& s)
{
// ok to refer to private members height and width of Screen class
s.height_ += r;
s.width_ += c;
return *this;
}

==================================================================================

// Screen Main.cpp

#include "Screen.h"
#include "Window_Mgr.h"

int main()
{
Window_Mgr w;
Screen s;
}

==================================================================================


This is the error I get:

Window_Mgr.obj : error LNK2005: "public: char __thiscall
Screen::get(unsigned int,unsigned int)const " (?get@Screen@@QBEDII@Z)
already defined in Screen Main.obj
1>C:\Documents and Settings\T\My Documents\Visual Studio 2005\Projects
\Language Tests\Debug\overload inline.exe : fatal error LNK1169: one
or more multiply defined symbols found

==================================================================================

I don't know why inlining the get(index, index) method fixes the
linking error.

I'm sure I am doing something wrong. Maybe it is the way I structure
the program to be able to use the friend declaration.

The error also goes away if I don't inline get(index, index) but take
out the lines involving Screen in the "Screen Main.cpp" file.

==================================================================================

2nd version of program:

It's even more complicated if instead of the "friend class Window_Mgr"
declaration, I make Window_Mgr::relocate a friend. In this case, I
get two linking errors:

1>Screen.obj : error LNK2005: "public: char __thiscall
Screen::get(unsigned int,unsigned int)const " (?get@Screen@@QBEDII@Z)
already defined in Screen Main.obj
1>Window_Mgr.obj : error LNK2005: "public: char __thiscall
Screen::get(unsigned int,unsigned int)const " (?get@Screen@@QBEDII@Z)
already defined in Screen Main.obj

==================================================================================

These errors are also fixed if I inline the get(index, index) method.

If I don't inline get(index, index) but take out the lines involving
Screen in the "Screen Main.cpp" file, I still get this error:

1>Window_Mgr.obj : error LNK2005: "public: char __thiscall
Screen::get(unsigned int,unsigned int)const " (?get@Screen@@QBEDII@Z)
already defined in Screen.obj
 
A

Alf P. Steinbach

* t:
I isolated a part of the code to quote for you, but found it you are
correct. The linking error I get is coming from a more complicated
situation that also involves a second class and a friend declaration.
Here is an abridged version (sorry I can't make it shorter):

==================================================================================

#ifndef SCREEN_H
#define SCREEN_H

#include <string>

// #include "Window_Mgr.h" // for 2nd version of program

class Screen
{
// for 2nd version of program
// friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index,
// Window_Mgr::index, Screen&);

friend class Window_Mgr;

public:
typedef std::string::size_type index;

char get() const
{ return contents_[cursor_]; }
char get(index r, index c) const;

private:
std::string contents_;
index cursor_;
index height_, width_;
};


// inline declared in the class declaration; no need to repeat on the
definition


This overload defined below is not declared inline in the class definition.

To define it in the header file it should be declared inline in the
class definition or here. When you /define/ a function in the class
definition it's automatically inline. When you just declare it it's
not, unless you explicitly declare it as "inline".

I now think you misunderstood what I wrote.

char Screen::get(index r, index c) const
{
index row = r * width_; // compute the row location
return contents_[row + c]; // offset by c to fetch specified
character
}

#endif

Cheers, & hth.,

- Alf
 
T

t

I think I understand what you posted earlier.

In the program I listed, I gave the version where the get() method is
inlined but the get(index, index) method is not inline. Ignore the
comment "// inline declared in the class declaration; no need to
repeat on the definition" as it doesn't apply to what the program
actually does here. I should have deleted that comment.

In a simpler program where I don't have the 2nd class and the friend
declaration, I see that I don't have to inline both get methods and
the program will compile and link. But the version I posted here will
not link. For some reason, it will link if I inline the get(index,
index) method.
 
B

Bo Persson

t wrote:
:: I think I understand what you posted earlier.
::
:: In the program I listed, I gave the version where the get() method
:: is inlined but the get(index, index) method is not inline. Ignore
:: the comment "// inline declared in the class declaration; no need
:: to repeat on the definition" as it doesn't apply to what the
:: program actually does here. I should have deleted that comment.
::
:: In a simpler program where I don't have the 2nd class and the
:: friend declaration, I see that I don't have to inline both get
:: methods and the program will compile and link. But the version I
:: posted here will not link. For some reason, it will link if I
:: inline the get(index, index) method.

If you define your function in a header file, and then include the
header in two or more implementation files, you will get several
copies of your non-inlined function. When the function is inlined, the
compiler/linker will fix this (somehow), when non-inlined the linker
is likely to complain.

This has nothing to do with overloading.


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top