Overloading << generates problems

P

pmatos

Hi all,

I have the following code:
class test {
public:
test(const std::string *n) : name(n) {}
virtual ~test() {}

const std::string * getName() { return name; }

protected:
const std::string * name; ///< Variable name.

private:
};

std::eek:stream& operator<<(std::eek:stream& s, const test& v) {
return s << v.getName();
}

And I get when I try to compile:
common/test.cc: In function `std::eek:stream& operator<<(std::eek:stream&,
const test&)':
common/test.cc:5: error: no matching function for call to `test
::getName() const'
common/test.h:14: error: candidates are: const std::string*
test::getName() <near match>
make: *** [test.o] Error 1

Any ideas on where the problem is?

Cheers,

Paulo Matos
 
M

Malte Starostik

pmatos said:
Hi all,

I have the following code:
class test {
public:
test(const std::string *n) : name(n) {}
virtual ~test() {}

const std::string * getName() { return name; }
const std::string * getName() const { return name; }
protected:
const std::string * name; ///< Variable name.

private:
};

std::eek:stream& operator<<(std::eek:stream& s, const test& v) {
return s << v.getName();
}

And I get when I try to compile:
common/test.cc: In function `std::eek:stream& operator<<(std::eek:stream&,
const test&)':
common/test.cc:5: error: no matching function for call to `test
::getName() const'
common/test.h:14: error: candidates are: const std::string*
test::getName() <near match>
make: *** [test.o] Error 1

Any ideas on where the problem is?

v is a const test&, so test::getName() needs to be const (should be
anyway, as it doesn't modify *this). Apart from that, are you sure
about the pointers? Shouldn't all those strings be references and
values where appropriate?

Cheers,
Malte
 
S

shabbir

The problem is you are calling a function getName() with const object
but the declaration of const does not happen to be const in that
fashion probably. Try putting the keyword at the last and that will
solve the current problem.
 
P

pmatos

shabbir said:
The problem is you are calling a function getName() with const object
but the declaration of const does not happen to be const in that
fashion probably. Try putting the keyword at the last and that will
solve the current problem.

Thanks all,

However, this solution enforces that through the operator<< overloading
I cannot access the class private parts. Since I'm overloading
operator<< for debuggins purposes only I would like to be able to print
them without getters for all of them. What's the best solution in this
situation? Having a print() method and then calling print() from the
operator<< overloading?

Cheers,

Paulo Matos
 
M

Marek Vondrak

I have the following code:
class test {
public:
test(const std::string *n) : name(n) {}
virtual ~test() {}

const std::string * getName() { return name; }

protected:
const std::string * name; ///< Variable name.

private:
};

std::eek:stream& operator<<(std::eek:stream& s, const test& v) {
return s << v.getName();
}

What about to make operator<< a friend of the test class:

class test {
....
friend std::eek:stream & operator<<( std::eek:stream & s, const test & v );
};

std::eek:stream& operator<<(std::eek:stream& s, const test& v) {
return s << v.name;
}

-- Marek
 
M

Malte Starostik

pmatos said:
Thanks all,

However, this solution enforces that through the operator<< overloading
I cannot access the class private parts. Since I'm overloading
operator<< for debuggins purposes only I would like to be able to print
them without getters for all of them. What's the best solution in this
situation? Having a print() method and then calling print() from the
operator<< overloading?

Either that or the usual way employing friendship. (Below with an
inline operator for brevity. If it's more complex than that, the
definition should be elsewhere):

class Foo
{
public:
Foo( const std::string& name )
: m_name( name ) {}
const std::string& name() const
{ return m_name; }

private:
std::string m_name;
friend void operator <<( std::eek:stream& s, const Foo& v )
{
return s << v.m_name;
}
};

Cheers,
Malte
 
K

Karl Heinz Buchegger

pmatos said:
Thanks all,

However, this solution enforces that through the operator<< overloading
I cannot access the class private parts. Since I'm overloading
operator<< for debuggins purposes only I would like to be able to print
them without getters for all of them. What's the best solution in this
situation? Having a print() method and then calling print() from the
operator<< overloading?

make the operator<< a friend of the class:

class test {

friend std::eek:stream& operator<<(std::eek:stream& s, const test& v);

public:
test(const std::string *n) : name(n) {}
virtual ~test() {}

const std::string * getName() const { return name; }

protected:
const std::string * name; ///< Variable name.

private:
};
 
P

pmatos

Malte said:
class Foo
{
public:
Foo( const std::string& name )
: m_name( name ) {}
const std::string& name() const
{ return m_name; }

private:
std::string m_name;
friend void operator <<( std::eek:stream& s, const Foo& v )
{
return s << v.m_name;
}

Should return std::eek:stream& instead of void, right?
Should it be declared private?

Paulo Matos
 
K

Karl Heinz Buchegger

pmatos said:
Should return std::eek:stream& instead of void, right?
right

Should it be declared private?

Why?
Don't you think it is a good idea if some code just can do:

int main()
{
Foo test;
cout << test << '\n';
}

No harm is done to the 'test' object by that. So if someone wants to
output it, well, let him do so!
 
M

Malte Starostik

pmatos said:
Malte Starostik wrote:




Should return std::eek:stream& instead of void, right?
Should it be declared private?
Sorry, of course it should return std::eek:stream&
It's not private, it's a free-standing inline friend function. More
verbose alternative, non-inline:

class Foo
{
//...
friend std::eek:stream& operator <<( std::eek:stream&, const Foo& );
};

std::eek:stream& operator <<( std::eek:stream& s, const Foo& v )
{
//...
}

Cheers,
Malte
 
B

BigBrian

I know this isn't what you were asking, but your code makes me
nervious. Where does the memory for test::name get created? Is it on
the stack? or on the heap? Is the test class responsible for deleting
it or not? What about the default copy constructor that the compiler
generates, it's a shallow copy, is that what you want?...

I realize that this class may be used only for illustration purposes,
but IMHO it has a lot of potential problems.
 

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

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,661
Latest member
FloridaHan

Latest Threads

Top