By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,127 Members | 1,160 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,127 IT Pros & Developers. It's quick & easy.

static member functions access to class members and methods

P: n/a
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
However, this doesn't seem entirely correct. It also doesn't mention
whether static member functions can access protected and private
member data and methods (and I couldn't spot this in the FAQ).

I have a class row<Row> which derives from row_base:

template<typename Row>
class row : public row_base
{
public:
typedef std::auto_ptr<Row> row_ptr;

row(): row_base() {}

row(row_state status, bool modified=false):
row_base(status, modified) {}

virtual ~row() {}

static row_ptr create(pqxx::result::const_iterator row,
pqxxobject::transaction& tran)
{
row_ptr p(new Row);
p->convert_impl(row, tran); // protected
p->row_base::m_state = STATE_INITIALISED; // private
return p;
}

virtual void convert_impl(pqxx::result::const_iterator row,
pqxxobject::transaction& tran) = 0;

}; // class row

Here, in the static create() method, row_base::m_state is a private
(enum) data member of the base class, yet I can assign it directly.
However, convert_impl() is a pure virtual function which is public
here and protected in the deriving class, but I get an error when I
compile:

places.cc: In static member function `static std::auto_ptr<_Tp1>
pqxxobject::row<Row>::create(pqxx::result::const_i terator,
pqxxobject::transaction&) [with Row = Place]':
.../pqxx-object/table.h:172: instantiated from `std::auto_ptr<std::list<Row, std::allocator<_CharT> > > pqxxobject::table<Row>::find_many(const std::string&) [with Row = Place]'
places.cc:207: instantiated from here
places.cc:175: error: `virtual void
Place::convert_impl(pqxx::result::const_iterator, pqxxobject::transaction&)'
is protected
.../pqxx-object/row.h:97: error: within this context

row.h:97 is the "p->convert_impl(row, tran);" line, above.

I can't see the rationale between being able to access private data
members, but not protected methods (which are actually public in the
row<> class)!
I would probably be better making create() call a specialised
protected constructor, but I'm interested in learning why the above
doesn't work.
Thanks,
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
Jul 22 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Roger Leigh wrote:
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
However, this doesn't seem entirely correct.
You're right. If your static member function has an object of the class,
it can access member variables of that object.
It also doesn't mention whether static member functions can access
protected and private member data and methods (and I couldn't spot
this in the FAQ).
It doesn't matter if the member is static or not. Any member function
can access any protected and private member of the same class.
I have a class row<Row> which derives from row_base:

template<typename Row>
class row : public row_base
{
public:
typedef std::auto_ptr<Row> row_ptr;

row(): row_base() {}

row(row_state status, bool modified=false):
row_base(status, modified) {}

virtual ~row() {}

static row_ptr create(pqxx::result::const_iterator row,
pqxxobject::transaction& tran)
{
row_ptr p(new Row);
p->convert_impl(row, tran); // protected
p->row_base::m_state = STATE_INITIALISED; // private
return p;
}

virtual void convert_impl(pqxx::result::const_iterator row,
pqxxobject::transaction& tran) = 0;

}; // class row

Here, in the static create() method, row_base::m_state is a private
(enum) data member of the base class, yet I can assign it directly.
However, convert_impl() is a pure virtual function which is public
here and protected in the deriving class, but I get an error when I
compile:

places.cc: In static member function `static std::auto_ptr<_Tp1>
pqxxobject::row<Row>::create(pqxx::result::const_i terator,
pqxxobject::transaction&) [with Row = Place]':
../pqxx-object/table.h:172: instantiated from
`std::auto_ptr<std::list<Row, std::allocator<_CharT> > >
pqxxobject::table<Row>::find_many(const std::string&) [with Row =
Place]'
places.cc:207: instantiated from here
places.cc:175: error: `virtual void
Place::convert_impl(pqxx::result::const_iterator,
pqxxobject::transaction&)' is protected
../pqxx-object/row.h:97: error: within this context

row.h:97 is the "p->convert_impl(row, tran);" line, above.

I can't see the rationale between being able to access private data
members, but not protected methods (which are actually public in the
row<> class)!


They are public in the row<> class, but you are declaring your pointer
as row_ptr, which in your case is an auto_ptr<Place>. So you're
accessing the object through a pointer to Place, where, as you say, the
member is protected, i.e. only Place itself and classes derived from
that can access it.

Jul 22 '05 #2

P: n/a
On Tue, 20 Jan 2004 12:48:55 +0100, Rolf Magnus wrote:
Roger Leigh wrote:
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
However, this doesn't seem entirely correct.


You're right. If your static member function has an object of the class,
it can access member variables of that object.


I guess it's a clumsy way of saying you have no this-pointer.

M4

Jul 22 '05 #3

P: n/a
Martijn Lievaart wrote:
On Tue, 20 Jan 2004 12:48:55 +0100, Rolf Magnus wrote:
Roger Leigh wrote:
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
However, this doesn't seem entirely correct.


You're right. If your static member function has an object of the
class, it can access member variables of that object.


I guess it's a clumsy way of saying you have no this-pointer.


It's not clumsy, it's just more explicit. Anyway, saying that static
members cannot access non-static members is just plain wrong.

Jul 22 '05 #4

P: n/a
On Tue, 20 Jan 2004 19:14:13 +0100, Rolf Magnus wrote:
Martijn Lievaart wrote:
On Tue, 20 Jan 2004 12:48:55 +0100, Rolf Magnus wrote:
Roger Leigh wrote:

The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
However, this doesn't seem entirely correct.

You're right. If your static member function has an object of the
class, it can access member variables of that object.


I guess it's a clumsy way of saying you have no this-pointer.


It's not clumsy, it's just more explicit. Anyway, saying that static
members cannot access non-static members is just plain wrong.


My bad, I was referring to the original statement, not your explanation. I
should have made that clearer.

M4

Jul 22 '05 #5

P: n/a
Roger Leigh <${******@invalid.whinlatter.uklinux.net.invalid > wrote in message news:<87************@wrynose.whinlatter.uklinux.ne t>...
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
The static functions can address only the static data of a class;
non-static data are unavailable to these functions. If non-static data
could be addressed, to which object would they belong? Any attempt
to access a normal class member will generate a compile time
error. Similarly, static functions cannot call non-static functions of
the class. All this is caused by the fact that static functions have
no this pointer.
However, this doesn't seem entirely correct. It also doesn't mention
whether static member functions can access protected and private
member data and methods (and I couldn't spot this in the FAQ).

I have a class row<Row> which derives from row_base:

template<typename Row>
class row : public row_base
{
public:
typedef std::auto_ptr<Row> row_ptr;

row(): row_base() {}

row(row_state status, bool modified=false):
row_base(status, modified) {}

virtual ~row() {}

static row_ptr create(pqxx::result::const_iterator row,
pqxxobject::transaction& tran)
{
row_ptr p(new Row);
p->convert_impl(row, tran); // protected
p->row_base::m_state = STATE_INITIALISED; // private
return p;
}

virtual void convert_impl(pqxx::result::const_iterator row,
pqxxobject::transaction& tran) = 0;

}; // class row

Here, in the static create() method, row_base::m_state is a private
(enum) data member of the base class, yet I can assign it directly.
However, convert_impl() is a pure virtual function which is public
here and protected in the deriving class, but I get an error when I
compile:

places.cc: In static member function `static std::auto_ptr<_Tp1>
pqxxobject::row<Row>::create(pqxx::result::const_i terator,
pqxxobject::transaction&) [with Row = Place]':
../pqxx-object/table.h:172: instantiated from `std::auto_ptr<std::list<Row, std::allocator<_CharT> > > pqxxobject::table<Row>::find_many(const std::string&) [with Row = Place]'
places.cc:207: instantiated from here
places.cc:175: error: `virtual void
Place::convert_impl(pqxx::result::const_iterator, pqxxobject::transaction&)'
is protected
../pqxx-object/row.h:97: error: within this context

row.h:97 is the "p->convert_impl(row, tran);" line, above.

I can't see the rationale between being able to access private data
members, but not protected methods (which are actually public in the
row<> class)!
I would probably be better making create() call a specialised
protected constructor, but I'm interested in learning why the above
doesn't work.
Thanks,
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----

Jul 22 '05 #6

P: n/a

"c++novice" <be**************@yahoo.com> wrote in message
news:34**************************@posting.google.c om...
Roger Leigh <${******@invalid.whinlatter.uklinux.net.invalid > wrote in message news:<87************@wrynose.whinlatter.uklinux.ne t>...
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".


The static functions can address only the static data of a class;
non-static data are unavailable to these functions. If non-static data
could be addressed, to which object would they belong? Any attempt
to access a normal class member will generate a compile time
error. Similarly, static functions cannot call non-static functions of
the class. All this is caused by the fact that static functions have
no this pointer.


No they can access any data and methods of the class - they just don't have
a 'this'.

However, this doesn't seem entirely correct. It also doesn't mention
whether static member functions can access protected and private
member data and methods (and I couldn't spot this in the FAQ).

I have a class row<Row> which derives from row_base:

template<typename Row>
class row : public row_base
{
public:
typedef std::auto_ptr<Row> row_ptr;

row(): row_base() {}

row(row_state status, bool modified=false):
row_base(status, modified) {}

virtual ~row() {}

static row_ptr create(pqxx::result::const_iterator row,
pqxxobject::transaction& tran)
{
row_ptr p(new Row);
p->convert_impl(row, tran); // protected
p->row_base::m_state = STATE_INITIALISED; // private
return p;
}

virtual void convert_impl(pqxx::result::const_iterator row,
pqxxobject::transaction& tran) = 0;

}; // class row

Here, in the static create() method, row_base::m_state is a private
(enum) data member of the base class, yet I can assign it directly.
However, convert_impl() is a pure virtual function which is public
here and protected in the deriving class, but I get an error when I
compile:

places.cc: In static member function `static std::auto_ptr<_Tp1>
pqxxobject::row<Row>::create(pqxx::result::const_i terator,
pqxxobject::transaction&) [with Row = Place]':
../pqxx-object/table.h:172: instantiated from `std::auto_ptr<std::list<Row, std::allocator<_CharT> > >
pqxxobject::table<Row>::find_many(const std::string&) [with Row = Place]' places.cc:207: instantiated from here
places.cc:175: error: `virtual void
Place::convert_impl(pqxx::result::const_iterator, pqxxobject::transaction&)' is protected
../pqxx-object/row.h:97: error: within this context

row.h:97 is the "p->convert_impl(row, tran);" line, above.
Are you certain because it seems to me that you shouldn't even be able to
create a row since you have
declared convert_impl pure virtual.

I can't see the rationale between being able to access private data
members, but not protected methods (which are actually public in the
row<> class)!
I would probably be better making create() call a specialised
protected constructor, but I'm interested in learning why the above
doesn't work.
Thanks,
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/ GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----

Jul 22 '05 #7

P: n/a
c++novice wrote:
Roger Leigh <${******@invalid.whinlatter.uklinux.net.invalid > wrote in
message news:<87************@wrynose.whinlatter.uklinux.ne t>...
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
The static functions can address only the static data of a class;
non-static data are unavailable to these functions. If non-static data
could be addressed, to which object would they belong?


Any object that is available to the function.
Any attempt
to access a normal class member will generate a compile time
error. Similarly, static functions cannot call non-static functions of
the class.
Just like a non-member-function can access non-static data of a class, a
static member function can. If you're still not convinced, explain
this:

#include <iostream>

class X
{
public:
static void foo(const X& x)
{
std::cout << x.text;
}

const char* text;
};

int main()
{
X x;
x.text = "Hello world!\n";
X::foo(x);
}

X::text is a non-static member of X, and still the static member
function does access it.
All this is caused by the fact that static functions have
no this pointer.


Right, they have no this pointer, but they can still access non-static
members of the class if they get an instance of that class. They just
are not called for a specific instance.

Jul 22 '05 #8

P: n/a
Rolf Magnus <ra******@t-online.de> wrote in message news:<bu*************@news.t-online.com>...
c++novice wrote:
Roger Leigh <${******@invalid.whinlatter.uklinux.net.invalid > wrote in
message news:<87************@wrynose.whinlatter.uklinux.ne t>...
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
The static functions can address only the static data of a class;
non-static data are unavailable to these functions. If non-static data
could be addressed, to which object would they belong?


Any object that is available to the function.
Any attempt
to access a normal class member will generate a compile time
error. Similarly, static functions cannot call non-static functions of
the class.


Just like a non-member-function can access non-static data of a class, a
static member function can. If you're still not convinced, explain
this:

#include <iostream>

class X
{
public:
static void foo(const X& x)
{
std::cout << x.text;
}

const char* text;
};

int main()
{
X x;
x.text = "Hello world!\n";
X::foo(x);
}

X::text is a non-static member of X, and still the static member
function does access it.


U r very much right because here an object of type X is passed in
static member function foo()as a parameter,
But foo() is not directly accessing the member like
std::cout << text;

All this is caused by the fact that static functions have
no this pointer.


Right, they have no this pointer, but they can still access non-static
members of the class if they get an instance of that class. They just
are not called for a specific instance.

Jul 22 '05 #9

P: n/a
Rolf Magnus <ra******@t-online.de> writes:
Martijn Lievaart wrote:
On Tue, 20 Jan 2004 12:48:55 +0100, Rolf Magnus wrote:
Roger Leigh wrote:>

The C++ book I have to hand (Liberty and Horvath, Teach yourself C++
for Linux in 21 Days--I know there are better) states that "static
member functions cannot access any non-static member variables".
However, this doesn't seem entirely correct.

You're right. If your static member function has an object of the
class, it can access member variables of that object.


I guess it's a clumsy way of saying you have no this-pointer.


It's not clumsy, it's just more explicit. Anyway, saying that static
members cannot access non-static members is just plain wrong.


Much of the book is like that. I found it fairly readable for the
basics of the language, but it leaves a lot of questions unanswered,
and the devil is always in the details.

I did get a copy of Stroustrup's TCPL from the library at the same
time, but as a C programmer with no OO knowledge, I was out of my
depth several pages into the introduction!! It would probably be OK
now I have a decent grasp of the language, but the 21 days books was
far more understandable at the time.
--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
Jul 22 '05 #10

P: n/a
Rolf Magnus <ra******@t-online.de> writes:
Roger Leigh wrote:
I have a class row<Row> which derives from row_base:

template<typename Row>
class row : public row_base
{
public:
typedef std::auto_ptr<Row> row_ptr;

row(): row_base() {}

row(row_state status, bool modified=false):
row_base(status, modified) {}

virtual ~row() {}

static row_ptr create(pqxx::result::const_iterator row,
pqxxobject::transaction& tran)
{
row_ptr p(new Row);
p->convert_impl(row, tran); // protected
p->row_base::m_state = STATE_INITIALISED; // private
return p;
}

virtual void convert_impl(pqxx::result::const_iterator row,
pqxxobject::transaction& tran) = 0;

}; // class row

Here, in the static create() method, row_base::m_state is a private
(enum) data member of the base class, yet I can assign it directly.
However, convert_impl() is a pure virtual function which is public
here and protected in the deriving class, but I get an error when I
compile: [...] I can't see the rationale between being able to access private data
members, but not protected methods (which are actually public in the
row<> class)!


They are public in the row<> class, but you are declaring your pointer
as row_ptr, which in your case is an auto_ptr<Place>. So you're
accessing the object through a pointer to Place, where, as you say, the
member is protected, i.e. only Place itself and classes derived from
that can access it.


Ah, that makes sense!

I've now got it working, but only after discovering a wart in the
language: the base class is a template and if I declare a pure virtual
(or virtual) function in the template, when I call the function it
does not call the derived version. It appears that virtual does not
work with templates at all :-\.

I've come up with two solutions: declare the function in the deriving
class public, so the template can call it directly (not desirable), or
keep it protected/private and make the base class a friend, so it can
call them even though they are protected (better, but still not
clean enough for my liking).

Is there a better alternative to these approaches? Basically, I'd
like to be able to fake virtual to achieve this effect:

template<typename T>
class foo {
public:
void func() { func_impl(); }
private:
virtual void func_impl();
}

class bar : public foo<int> {
private:
virtual void func_impl();
}

i.e. when I do this:
bar c;
c.func()
c.func_impl() gets called by foo<int>::func().

Thanks,
Roger

--
Roger Leigh

Printing on GNU/Linux? http://gimp-print.sourceforge.net/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 100,000 Newsgroups - 19 Different Servers! =-----
Jul 22 '05 #11

P: n/a
Roger Leigh wrote:
I did get a copy of Stroustrup's TCPL from the library at the same
time, but as a C programmer with no OO knowledge, I was out of my
depth several pages into the introduction!! It would probably be OK
now I have a decent grasp of the language, but the 21 days books was
far more understandable at the time.


Try skipping the intro. If you already have some familiarity with C,
the first few chapters of TC++PL should be mostly review for you, and
get you up to speed quickly on C++ as a "better C."

Jul 22 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.