Newbie : friend function problem

M

mark page

Hi to all

I am a newcomer to C++ and I am working my way through the book "C++ Primer
Third Edition".

I have a problem with one example and I am given the error message

: error C2248: 'hours' : cannot access private member declared in class
'Time'
: error C2248: 'minutes' : cannot access private member declared in class
'Time'

The problem relates to a Class Time and within it I have defined a friend
function (that has overloaded the << operator) to access the private data
members.

When I program the function inline within the class definition everthing
works, However, when the function definition is defined outside the class I
have the above problem. I am using the Visual C++ compiler version 6.

here is the code and I have highlighted the offending function with
comments.
// mytime.h -- class definition for time class
// demonstrates an overloaded operator for the Addition member
// includes friend functions

#ifndef _MYTIME_H_
#define _MYTIME_H_
#include <iostream>
using namespace std;

class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time & t) const; // overloading the + operator to add
objects
Time operator-(const Time & t) const; // overloading the - operator to
subtract objects
Time operator*(double n) const; // overloading the * operator to
multiply objects by a factor
friend Time operator*(double m, const Time & t)
{ return t * m;} // inline definiton
// ************ problem function *********************
friend ostream & operator<<(ostream & os, const Time & t);

};
#endif


// mytime.cpp -- Time class method definitions

#include "mytime.h"

Time::Time()
{
hours = minutes = 0;
}

Time::Time(int h, int m)
{
hours = h;
minutes = m;
}

void Time::AddMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}

void Time::AddHr(int h)
{
hours += h;
}

void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}

Time Time::eek:perator +(const Time & t) const // overloading the + operator
to add objects
{
Time sum;
sum.minutes = minutes + t.minutes;
sum. hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}

Time Time::eek:perator-(const Time & t) const // overloading the - operator to
subtract objects
{
Time diff;
int tot1, tot2;
tot1 = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - tot1) % 60;
diff.hours = (tot2 - tot1) / 60;
return diff;
}

Time Time::eek:perator*(double mult) const // overloading the * operator to
multiply objects by a factor
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}

// ***** problem function *********************************

ostream & operator<<(ostream & os, const Time & t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}


please help

mark
 
A

Alf P. Steinbach

I am a newcomer to C++ and I am working my way through the book "C++ Primer
Third Edition".

I have a problem with one example and I am given the error message

: error C2248: 'hours' : cannot access private member declared in class
'Time'
: error C2248: 'minutes' : cannot access private member declared in class
'Time'

Be glad for this message. The compiler tells you (for the wrong reasons,
but never mind that... ;-)) that your class is incomplete: it lacks necessary
functionality for extracting hours and minutes. VC7 compiles the code just fine,
but with an important warning that I indicate below, just as g++ 3.2.2 does.

Btw., I would have designed this as at least two classes: one for time
arithmetic, with no silly hours and minutes and such around, and one for
only conversion to and from sexagesimal. Also consider the difference
between a time span and a specific moment in time. These should be
different classes (now we're up to three).

Check out the time support in Boost, [http://www.boost.org].


The problem relates to a Class Time and within it I have defined a friend
function (that has overloaded the << operator) to access the private data
members.

When I program the function inline within the class definition everthing
works, However, when the function definition is defined outside the class I
have the above problem. I am using the Visual C++ compiler version 6.

here is the code and I have highlighted the offending function with
comments.
// mytime.h -- class definition for time class
// demonstrates an overloaded operator for the Addition member
// includes friend functions

#ifndef _MYTIME_H_
#define _MYTIME_H_
#include <iostream>

Generally not a good idea to drag <iostream> into a headerfile.

In addition, it's far more than you actually use.

Consider moving that to-stream functionality to a separate, related
header+implementation.


using namespace std;

Absolutely not a good idea in a headerfile.



class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time & t) const; // overloading the + operator to add
objects
Time operator-(const Time & t) const; // overloading the - operator to
subtract objects
Time operator*(double n) const; // overloading the * operator to
multiply objects by a factor
friend Time operator*(double m, const Time & t)
{ return t * m;} // inline definiton
// ************ problem function *********************
friend ostream & operator<<(ostream & os, const Time & t);

};
#endif


// mytime.cpp -- Time class method definitions

#include "mytime.h"

Time::Time()
{
hours = minutes = 0;
}

Time::Time(int h, int m)
{
hours = h;
minutes = m;
}

void Time::AddMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}

void Time::AddHr(int h)
{
hours += h;
}

void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}

Time Time::eek:perator +(const Time & t) const // overloading the + operator
to add objects
{
Time sum;
sum.minutes = minutes + t.minutes;
sum. hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}

Time Time::eek:perator-(const Time & t) const // overloading the - operator to
subtract objects
{
Time diff;
int tot1, tot2;
tot1 = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - tot1) % 60;
diff.hours = (tot2 - tot1) / 60;
return diff;
}

Time Time::eek:perator*(double mult) const // overloading the * operator to
multiply objects by a factor
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;

warning C4244: 'initializing' : conversion from 'double' to 'long', possible loss of data


result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}

// ***** problem function *********************************

ostream & operator<<(ostream & os, const Time & t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}

VC6 had some severe problems with combinations of namespace, class and
template. Perhaps it will compile if you remove that "using namespace
std;" and use explicit namespace qualification. Just a thought.
 
R

Ron Natalie

mark page said:
#ifndef _MYTIME_H_
#define _MYTIME_H_

You are not permitted to use identifiers that begin wtih _ followed by an uppercase
letter. These are reserved for the implementation.
#include <iostream>
using namespace std;

Do NOT put using directives in any file you expect others to use. You're free
to pollute your own namespace, but others should not find the std namespace
included just because they used your include file. Best to just use the fully
qualified names in your include files.


What you wrote seems to work fine in VC6 (with service packs).
 
D

David Waern

Hi. Is there a way to specify a common interface for different
implementations of a handle class for a certain resource when
using the RAII idiom?

Take a network socket interface that is implemented by different classes
for different platforms. The contructors of the classes receive parameters
and acquire the resource. How would you describe that commonality in an
abstract interface when constructors cannot be declared pure virtual?

/David Waern
 
A

Alf P. Steinbach

Hi. Is there a way to specify a common interface for different
implementations of a handle class for a certain resource when
using the RAII idiom?

Take a network socket interface that is implemented by different classes
for different platforms. The contructors of the classes receive parameters
and acquire the resource. How would you describe that commonality in an
abstract interface when constructors cannot be declared pure virtual?

I suspect that your example is simply badly chosen. All you need is a
fixed declaration, and different implementation files for that class for
different platforms. That's trivial.

The more general problem of handle to different beasts is not much more
interesting. All you need is a factory for each 'handled' class. This
can be greatly elaborated, called a 'pattern' (handle-pattern! wow), and
so on, but the upshot is the factory idea, a virtual factory function.

Things start to get interesting when you have a hierarchy of handle
classes corresponding to a hierarchy of implementation classes, but that
still hasn't anything to do with declaring constructors virtual.
 
M

mark page

Thanks very much for your help I used the explicit namespace qualification
and all is well. Lesson well learnt !


Alf P. Steinbach said:
I am a newcomer to C++ and I am working my way through the book "C++ Primer
Third Edition".

I have a problem with one example and I am given the error message

: error C2248: 'hours' : cannot access private member declared in class
'Time'
: error C2248: 'minutes' : cannot access private member declared in class
'Time'

Be glad for this message. The compiler tells you (for the wrong reasons,
but never mind that... ;-)) that your class is incomplete: it lacks necessary
functionality for extracting hours and minutes. VC7 compiles the code just fine,
but with an important warning that I indicate below, just as g++ 3.2.2 does.

Btw., I would have designed this as at least two classes: one for time
arithmetic, with no silly hours and minutes and such around, and one for
only conversion to and from sexagesimal. Also consider the difference
between a time span and a specific moment in time. These should be
different classes (now we're up to three).

Check out the time support in Boost, [http://www.boost.org].


The problem relates to a Class Time and within it I have defined a friend
function (that has overloaded the << operator) to access the private data
members.

When I program the function inline within the class definition everthing
works, However, when the function definition is defined outside the class I
have the above problem. I am using the Visual C++ compiler version 6.

here is the code and I have highlighted the offending function with
comments.
// mytime.h -- class definition for time class
// demonstrates an overloaded operator for the Addition member
// includes friend functions

#ifndef _MYTIME_H_
#define _MYTIME_H_
#include <iostream>

Generally not a good idea to drag <iostream> into a headerfile.

In addition, it's far more than you actually use.

Consider moving that to-stream functionality to a separate, related
header+implementation.


using namespace std;

Absolutely not a good idea in a headerfile.



class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time & t) const; // overloading the + operator to add
objects
Time operator-(const Time & t) const; // overloading the - operator to
subtract objects
Time operator*(double n) const; // overloading the * operator to
multiply objects by a factor
friend Time operator*(double m, const Time & t)
{ return t * m;} // inline definiton
// ************ problem function *********************
friend ostream & operator<<(ostream & os, const Time & t);

};
#endif


// mytime.cpp -- Time class method definitions

#include "mytime.h"

Time::Time()
{
hours = minutes = 0;
}

Time::Time(int h, int m)
{
hours = h;
minutes = m;
}

void Time::AddMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}

void Time::AddHr(int h)
{
hours += h;
}

void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}

Time Time::eek:perator +(const Time & t) const // overloading the + operator
to add objects
{
Time sum;
sum.minutes = minutes + t.minutes;
sum. hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}

Time Time::eek:perator-(const Time & t) const // overloading the - operator to
subtract objects
{
Time diff;
int tot1, tot2;
tot1 = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - tot1) % 60;
diff.hours = (tot2 - tot1) / 60;
return diff;
}

Time Time::eek:perator*(double mult) const // overloading the * operator to
multiply objects by a factor
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;

warning C4244: 'initializing' : conversion from 'double' to 'long', possible loss of data


result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}

// ***** problem function *********************************

ostream & operator<<(ostream & os, const Time & t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}

VC6 had some severe problems with combinations of namespace, class and
template. Perhaps it will compile if you remove that "using namespace
std;" and use explicit namespace qualification. Just a thought.
 
S

Stanley Yue

mark page said:
Hi to all

I am a newcomer to C++ and I am working my way through the book "C++ Primer
Third Edition".

I have a problem with one example and I am given the error message

: error C2248: 'hours' : cannot access private member declared in class
'Time'
: error C2248: 'minutes' : cannot access private member declared in class
'Time'

The problem relates to a Class Time and within it I have defined a friend
function (that has overloaded the << operator) to access the private data
members.

When I program the function inline within the class definition everthing
works, However, when the function definition is defined outside the class I
have the above problem. I am using the Visual C++ compiler version 6.

here is the code and I have highlighted the offending function with
comments.
// mytime.h -- class definition for time class
// demonstrates an overloaded operator for the Addition member
// includes friend functions

#ifndef _MYTIME_H_
#define _MYTIME_H_
#include <iostream>
using namespace std;

class Time
{
private:
int hours;
int minutes;
public:
Time();
Time(int h, int m = 0);
void AddMin(int m);
void AddHr(int h);
void Reset(int h = 0, int m = 0);
Time operator+(const Time & t) const; // overloading the + operator to add
objects
Time operator-(const Time & t) const; // overloading the - operator to
subtract objects
Time operator*(double n) const; // overloading the * operator to
multiply objects by a factor
friend Time operator*(double m, const Time & t)
{ return t * m;} // inline definiton
// ************ problem function *********************
friend ostream & operator<<(ostream & os, const Time & t);

};
#endif


// mytime.cpp -- Time class method definitions

#include "mytime.h"

Time::Time()
{
hours = minutes = 0;
}

Time::Time(int h, int m)
{
hours = h;
minutes = m;
}

void Time::AddMin(int m)
{
minutes += m;
hours += minutes / 60;
minutes %= 60;
}

void Time::AddHr(int h)
{
hours += h;
}

void Time::Reset(int h, int m)
{
hours = h;
minutes = m;
}

Time Time::eek:perator +(const Time & t) const // overloading the + operator
to add objects
{
Time sum;
sum.minutes = minutes + t.minutes;
sum. hours = hours + t.hours + sum.minutes / 60;
sum.minutes %= 60;
return sum;
}

Time Time::eek:perator-(const Time & t) const // overloading the - operator to
subtract objects
{
Time diff;
int tot1, tot2;
tot1 = t.minutes + 60 * t.hours;
tot2 = minutes + 60 * hours;
diff.minutes = (tot2 - tot1) % 60;
diff.hours = (tot2 - tot1) / 60;
return diff;
}

Time Time::eek:perator*(double mult) const // overloading the * operator to
multiply objects by a factor
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}

// ***** problem function *********************************

ostream & operator<<(ostream & os, const Time & t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}


please help

mark

I think the error is come from your compiler.
In my compiler ,your program is ok. check your compiler , fix it !
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top