How do I solve the one-way protection?

  • Permalink
  • submit to reddit
  • Email
  • Follow


Hi!

I want to use the compiler to force correct initialization by forcing 
certain functions to be implemented in the subclasses (pure virtual 
functions only reach the first subclass). In my example below we can 
assume that the base class must be initialized by collecting, say class 
names.

class Base
{
public:
    Base();

protected:
    template<class T>
    void init_()
    {
       std::string cn = static_cast<T*>(this)->getClassName_();
       ... store cn in a list ...
    }
};

class Derived1 : public Base
{
public:
    Derived1() { init_<Derived1>(); }

protected:
    std::string getClassName_() const { return "Number 1"; }
};

class Derived2 : public Derived1
{
public:
    Derived2() { init_<Derived2>(); }

protected:
    std::string getClassName_() const { return "Number 2"; }
};


This does not compile unless I make getClassName_() public. Why is 
protection one-way and how can I get around it?


Thanks,
Daniel

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply DeMarcus 8/6/2009 10:05:54 PM

See related articles to this posting


>    template<class T>
>    void init_()
>    {
>       std::string cn = static_cast<T*>(this)->getClassName_();
>       ... store cn in a list ...
>    }
> [...]
> This does not compile unless I make getClassName_() public. Why is
> protection one-way and how can I get around it?

When you convert "this" to a generic "T*" using static_cast<>, you no
longer benefit from being able to access protected members of T, even if
  T is the class you're calling from. For the simple reason that T can
now be anything, including "int" or "std::string". The compiler will
assume that you know what you're doing and T does have an accessible
(read: public) getClassName_() function, but no more than that.

You really don't need templates at all for what you're doing, that is
you can solve your problem either with templates, but no virtual
functions (in which case your member function needs to be public for the
reasons stated above), or without templates and with virtual member
functions, where you define getClassName_() as pure virtual in Base, and
simply call:

std::string cn = getClassName_();

in init_(). This will call the correct function for your objects.


-- 
Razvan Cojocaru
KeyID: 0x04CA34DE

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Razvan 8/7/2009 12:37:54 PM

On Aug 7, 12:05 am, DeMarcus <use_my_alias_h...@hotmail.com> wrote:
> Hi!
>
> I want to use the compiler to force correct initialization by forcing
> certain functions to be implemented in the subclasses (pure virtual
> functions only reach the first subclass). In my example below we can
> assume that the base class must be initialized by collecting, say class
> names.
>
> class Base
> {
> public:
>     Base();
>
> protected:
>     template<class T>
>     void init_()
>     {
>        std::string cn = static_cast<T*>(this)->getClassName_();
>        ... store cn in a list ...
>     }
>
> };
>
> class Derived1 : public Base
> {
> public:
>     Derived1() { init_<Derived1>(); }
>
> protected:
>     std::string getClassName_() const { return "Number 1"; }
>
> };
>
> class Derived2 : public Derived1
> {
> public:
>     Derived2() { init_<Derived2>(); }
>
> protected:
>     std::string getClassName_() const { return "Number 2"; }
>
> };
>
> This does not compile unless I make getClassName_() public. Why is
> protection one-way and how can I get around it?
>
> Thanks,
> Daniel

I think you've got to declare Base a friend in each derived class.
At least that's what people sometimes do with Curiously Recurring
Template Pattern, and your case is somewhat similar to CRTP.

Note that unless getClassName_ should be called from more
derived classes, you should declare them private, not protected.


HTH,
   Andy.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Andrew 8/7/2009 12:40:44 PM

On 7 Aug, 05:05, DeMarcus <use_my_alias_h...@hotmail.com> wrote:
> Hi!
>
> I want to use the compiler to force correct initialization by forcing
> certain functions to be implemented in the subclasses (pure virtual
> functions only reach the first subclass). In my example below we can
> assume that the base class must be initialized by collecting, say class
> names.
>
> class Base
> {
> public:
>     Base();
>
> protected:
>     template<class T>
>     void init_()
>     {
>        std::string cn = static_cast<T*>(this)->getClassName_();
>        ... store cn in a list ...
>     }
>
> };
>
> class Derived1 : public Base
> {
> public:
>     Derived1() { init_<Derived1>(); }
>
> protected:
>     std::string getClassName_() const { return "Number 1"; }
>
> };
>
> class Derived2 : public Derived1
> {
> public:
>     Derived2() { init_<Derived2>(); }
>
> protected:
>     std::string getClassName_() const { return "Number 2"; }
>
> };
>
> This does not compile unless I make getClassName_() public. Why is
> protection one-way and how can I get around it?

There are two issues here: Why is protection one way? and How to get
the class name in the base class constructor?

Why is protection one way?
(A) I would think that most people would consider it unnatural to
allow special access to base classes. After all a base class is not
supposed to depend on the declaration of its derived classes (Although
it can depend on the definitions using virtual methods).
(B) What would you expect from:  Derived2()
{ init_<CompletelyUnrelated>(); }
(C) In general it is not valid to call ANY derived class member
function from a base class constructor because the derived object is
not constructed at that point. (This is why virtual methods aren't
virtual in a constructor)

How to get that class name to the base class constructor:
Short answer: Provide a protected constructor in the base class that
takes it as parameter.
Note that you never NEED to call a derived class member in a base
class constructor because it can never return anything that couldn't
have been passed as a parameter.
Occasionally it can be useful to have a STATIC derived class function
to compute the constructor parameter if this is complex.
In this specific example there is no reason for getClassName_ to not
be static as it does not depend on object state:

cn = T::getClassName_();


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Nick 8/7/2009 12:41:39 PM
comp.lang.c++.moderated 10665 articles. 10 followers. Post

3 Replies
150 Views

Similar Articles

[PageSpeed] 53


  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

One Way -- Two Way?
I understand that the Windows XP firewall blocks incoming but not outgoing. If one uses an AV program and one or more spyware/malware programs, Is the One-Way Windows XP firewall adequate? Thanks for advice/opinions Carl On Tue, 9 Nov 2004 17:09:53 -0700, Carl spoketh >I understand that the Windows XP firewall blocks incoming but not outgoing. >If one uses an AV program and one or more spyware/malware programs, >Is the One-Way Windows XP firewall adequate? > >Thanks for advice/opinions >Carl > If you have anti-virus software, and scan your system for spyware every so...

Can you solve my one way ping problem ?
OS=Win2K Pro When "Deterministic Network Enhancer" is loaded, I can ping other machines on the LAN by IP, but they can't ping me. If I uninstall this service and reboot, all is well. When it is installed, no one can ping me even if I don't check the boxes to make the service inacative for the adapter. Unfortunately, the Cisco VPN that I use on the road requires that this service be installed. Any clues or ideas (other than uninstalling and installing as required) ? Thanks. GS ...

Both way and one way relationships
hello My book claims there are two kinds of relationships: Two way connection and one way connection, but it doesn't go into any more details. Anyways, here are the graphical representations that my book uses for displaying two way and one way relationships: <<---------->> //this is two way many-to-many connection <------------>> // this is two way one-to-many connection -------------->> // this is one way one-to-many connection At first I thought that one way connection would be between primary key in a row and all other no...

One-to-Many Corba one-way call
Hi all, I have read somewhere that it is possible to call a method on every instance of an object (one-to-many call on a group); my application is a distibuted system, and I want objects on remote nodes to all act the same. I would have no return value on those calls. From the material I have read so far, it also seems possible to use multi-cast or broadcast protocols (eg UDP) to distribute those one-to-many calls. Is this possible using TAO ? Can someone point me to ressources (articles or samples) going in that direction ? Any previous experience and comment would be nice, Thanks Jul...

is there a way ..... any way
Hello folks, I tried lurking on but it stays jibberish to me. Questions asked are responded with a jargon that is beyond my comprehension and often in a tone you'll think twice to ask the next question. So this is too heavy for me (yet?). Is there a way that simple mortals can ask questions how to do things with perl/ work with perl. Is there a newsgroup? ok ok RTFM you'll say. Obviously you don't understand my question and despair. Andries Meijer Andries wrote: > I tried lurking on but it stays jibberish to me. Questions asked > are responded with a jargon that is beyon...

Shortest way to read all lines (one by one) from a text file?
Ok, I know in general a way to read text lines ony-by-one from a file into a string variable. But I miss somehow a short one-liner like: foreach(String currentline : file("D:\test\myfile.txt")) { .... } Is there something like this in Java? What would be the shortest way otherwise? Robin On 2/11/11 4:20 PM, Robin Wenger wrote: > Ok, I know in general a way to read text lines ony-by-one from a file into a string variable. > But I miss somehow a short one-liner like: > > foreach(String currentline : file("D:\test\myfile.txt&qu...

there is more than one way to do it...
Unfortunately, I never remember any. Luca On Dec 5, 10:37=A0pm, luca <luca_rem...@alice.it> wrote: > Unfortunately, I never remember any. > > Luca Learn (at least READ) all the ways, and remember the easiest ;-) ...

Solve this one
Know someone who wants to set up two clients coming off a server (via wireless NICs). This server will be attached to a cable modem and the problem is he was told that since he doesn't have a static IP that the clients will eventually come up with unable to connect when browsing Internet. They said its impossible for these clients to stay on unless he purchases a perm. IP address for 79.00 /month. Any ideas out there? Also if you can recommend a Cisco router or similar device that will work around this. Doesn't have a lot of money since its for home. Thanks for any input. In ...

There's Gotta Be A Better Way #3: To One Or Not To One
So I want 1 or -1 at random. This looks verbose: (- 1 (* 2 (random 2))) Thoughts? ken -- Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm "Well, I've wrestled with reality for thirty-five years, Doctor, and I'm happy to state I finally won out over it." -- Elwood P. Dowd "I'll say I'm losing my grip, and it feels terrific." -- Smiling husband to scowling wife, New Yorker cartoon Ken Tilton <kentilton@gmail.com> writes: > So I want 1 or -1 at random. This looks verbose: > > (- 1 (* 2 (random 2))) > > Th...

one to one
How would you create a one to one relationship in FMP 9? I am practicing with setting up relationships and would like to experiment with this but all of mine are coming up one to many. lariveesl <lariveeslNO@yahooSPAM.com> wrote: > How would you create a one to one relationship in FMP 9? I am practicing > with setting up relationships and would like to experiment with this but all > of mine are coming up one to many. It's the same thing. You may want to make sure no one creates more than one child record using privileges, custom menus and scripts. -- http://clk...

one to one
Hi all, I have two datasets X and Y. See the below code. data X; input a ; cards; 100 200 300 ; data Y; input a; cards; 10 20 30 ; data Z; set X; if _n_ = 3; set Y; run; I know this is one to one reading. output: a 10 how this step will work internally. Well first your are reading in dataset X but you said to keep only the third observation. But you are also reading in dataset Y at the same time and it also keeps the third observation. Since X and Y has the same field a, SAS keeps the value from Y because it was called later. Make sense? "Ravi" wrote in message news:a...

One to One
I am trying to create a one to one releationship between two tables. The tables and the constraints are described below. I do not believe that I am accomplishing my goal.May I please have a input? The business rull is that one person should exist as the primary contact for the customer. CREATE TABLE CUSTOMER ( customer_id NUMBER NOT NULL, customer_type VARCHAR2(32 BYTE) NOT NULL, customer_display_name VARCHAR2(35 BYTE) NOT NULL, primary_contact_id NUMBER NOT NULL, CONSTRAINT pk_customer PRIMARY KEY (customer_id), CONSTRAINT idx_primary_contact UNIQUE (...

one-to-one
Does anyone have any opinions or comments on one-to-one relationships? I'm working on developing a single-table database I inherited into something that I hope will be a little more useful. The database contains records of individuals including both members and non-members of our organization. There are a number of attributes that apply only to members--orientation date, officer status and such--and I'm wondering whether it might make sense to have a separate table just for members with those fields rather than cluttering up the general table for individuals with attributes that...

tcp/ip network: one way ping on one machine
I have a local network with 3 machines running XP Pro. All machines can communicate with each other and the Internet. They can even see each other in the Network Places screen. Here is the issue: I can ping from everywhere to anywhere except one machine which will not accept a ping but can send one out to anywhere and get a response. When I try to ping that machine with its own IP address it times out. Not the case with the other two machines that respond properly. This particular machine sees everyone else in the Explorer, Network Places and the like but cannot respond to any...

One way to do it
Create perfect white noise by generating random phase in the frequency domain, and then multiply it by your PSD. Then transfer it to the time domain...Take note that MATLAB expects the conjugate symmetric part of the spectrum to be the second half of the array. Example is below, assuming you have your PSD handy. function [waveTs, time] = TimeseriesFromPSD(PSD, fs, T) % Create timeseries from a given double-sided PSD % % Create perfect white noise by generating random phase in the frequency % domain, and then multiply it by your PSD. Then transfer it to the time % domain...Take note ...

Free I-pod...one of the easiest and cheapest ways you will get one.
Hey- Check out this site thats givin away FREE iPods! Its the easiest way you're gonna get one. All you have to do is join,do a little survey, Try out a free trial of something, cancel if you want right after, and refer 5 friends to do the same. Think about how much an iPod costs...like 250 bucks. please help me out. i need one. click this exact link to join, or copy and paste it into a browser: http://www.freeiPods.com/?r=13185550 ...

what are the other ways to prevent a class from being subclassed. one way is to declare the class final.
Hi All, what are the other ways to prevent a class from being subclassed. one way is to declare the class final. Thanks Srinivas You could throw an exception in the ctor, if it's being called on a derived class: class NoExtend { public NoExtend() { if (this.getClass() != NoExtend.class) { throw new RuntimeException(); } } } Or you could have a private ctor, with a public factory method: class NoExtend { private NoExtend() { } public static NoExtend create() { return new NoExtend(); } } Those are two methods that come to mind... Walter ---- Walter...

using homotopy continuation equation to solve one equation with one unknown
I always encounter an error message for the code i have constructed below, fstring = [{'x/(1-x)-5*log10(0.4*(1-x)/(0.4-0.5*x))+4.45977'}]; varlist = [{'x'}]; %%%%%%%%%% Step 2: Make some choices for your problem: %%% choose the initial values for your variable initialval = [0]; %%% choose the limits for your solutions aboxa = [-100,100] ; %%% choose an upper value for s (in the ode system) upS =1; %%% choose the number of intermediate checks for [0, upperS] checks = 70; %%% choose an homotopy : FP or N homoto = 'FP'; %homoto = 'N'; %%% choose an...

re: There's Gotta Be A Better Way #3: To One Or Not To One
Ken Tilton wrote: > So I want 1 or -1 at random. This looks verbose: > > (- 1 (* 2 (random 2))) > > Thoughts? Clojure: user=> (rand-nth [-1 1]) 1 user=> (rand-nth [-1 1]) -1 user=> (rand-nth [-1 1]) -1 user=> (rand-nth [-1 1]) -1 user=> (rand-nth [-1 1]) 1 ...

what is the correct way to pass a multi-dimensional array into a function that expects a one-dimensional one?
Hello, The question comes in the context of Intel's MKL FFT function which is capable of computing a multi-dimensional FT. The calling method is as follows: status = DftiComputeForward( desc_handle, x_inout ) where x_inout is expected to be a one-dimensional array as is evident from the interface of DftiComputeForward : INTERFACE DftiComputeForward FUNCTION some_actual_function_1(desc,sSrcDst) INTEGER some_actual_function_1 REAL(4), INTENT(INOUT), DIMENSION(*) :: sSrcDst ... END FUNCTION some_actual_function_1 ... END INTERFACE DftiComputeForward MKL&#...

From formal to semi-formal: knowledge representation and problem solving in the AI way and the wiki way
From formal to semi-formal: knowledge representation and problem solving in the AI way and the wiki way 1. Failure of the formal way to represent encyclopedic knowledge Big thinkers like Leibniz, Dijkstra and John McCarthy all dreamed about an encyclopedia written in formal language and an automated reasoner that could solve a problem by reasoning on this formal knowledge base. Unfortunately attempts at this like the Cyc project still have a long way to go. 2. Success of the semi-formal way to represent encyclopedic knowledge In contrast, Wikipedia is a big success. Most stuff on Wikipedia i...

Is imp/exp the best way to move one schema from one inst to another? Please help!
Using oracle 9.2.0.3.0, on two Sun Starfire Servers both running Sun Unix, 8 Sparc CPUs, 2 TB each. We have a schema AP on an instance A1 on a UNIX server A1. The schema has tables, views, constraints, no triggers, functions, procs, indexes etc. We have another schema AP on an instance T1 on a UNIX server T1. The schema has tables, views, constraints, no triggers, functions, procs, indexes etc. We have made major changes to AP on A1 and we want to blow away AP on T1 and replace it completely with AP from A1. What is the best method of doing this? Will an export/import do it, export ...

One man,one goat,one cabbage and one wolf
Hi, I have tried to solve the problem mentioned in the subject. What I wrote doesn't go through all possibilities up to depth 8(which is what I wanted). We are trasnfering the objects from Left -> Right If at any time the Left bank remains empty then we immediately exit. The sideGood predicate assures that the side is in conformity with our rules (there should be no [wolf,goat] pair or [goat,cabbage] pair on that side). So,it can be tested with traverse([wolf,cabbage,goat],[],0). However,it does not hit a solution(altough it was expected to do so because depth has been limited to 8,and...

one way connection
I have a desktop running XP wired to my router. I have a laptop (XP) wirelessly connecting to the router. The desktop can see the laptop's shared folders and read and write to them, but the laptop can't see the desktop. If anyone can help or recommend a step by step site, I'd appreciate it. Simply running the MS wizards is definitely not getting the job done. fin On Tue, 28 Nov 2006 23:31:25 GMT, finbogey <nospam@nospam.com> wrote: >I have a desktop running XP wired to my router. I have a laptop (XP) >wirelessly connecting to the router. The desktop can see the lapt...