enforce access to derived class via pointer to base

M

Mark

Given

# include<iostream>
# include <string>

struct Datalink{};

template <typename Impl>
class data_access_base
{
public:

void read(const std::string& query, Datalink& in )
{
std::cout << " data_access_base::read ( query,Datalink) " <<
std::endl;
impl()->read(query,in);
}
void read(const std::string& query )
{
std::cout << " data_access_base::read ( query )" << std::endl;
impl()->read(query);
}

private:

Impl* impl() { return static_cast< Impl* >( this ); }

};


class crtp_a : public data_access_base<crtp_a>
{
public:
void read( const std::string& query, Datalink& in )
{
std::cout << "crtp_a::read - Datalink" << std::endl;
}


};

class crtp_b : public data_access_base <crtp_b>
{
public:

void read(const std::string& query)
{
std::cout << " crtp_b::read " << std::endl;
// actual implementation here
}
};

template < typename T >
data_access_base <T> access ( unsigned int xx ) {
if ( xx <= 2) {
crtp_base<crtp_a>* pa = new crtp_a;
return pa ;
} else {
crtp_base<crtp_b>* pb = new crtp_b;
return pb ;
}
}


int main ()
{
//option 1
{
Datalink inn;
data_access_base<crtp_a>* pa = new crtp_a ;
pa->read ( "test", inn ) ;
data_access_base<crtp_b>* pb = new crtp_b ;
pb->read ( "test" ) ;
}
//option 2
{
Datalink inn;
crtp_a xxx;
xxx.read ( "test", inn ) ;
crtp_b pp ;
pp.read ( "test" ) ;
}
std::cin.get();

}


Clients - via option 2 can create derived instances, then invoke
appropriate read methods, which is not what I want since this
circumvents the pimpl approach in the base class data_access_base.
How can I prevent clients from creating derived instances? Simply
put I want to enforce option 1.

2/ How do I get the return type of the access class to reflect either
a pointer to: crtp_base<crtp_a> or crtp_base<crtp_b>?
 
M

Mark

It seems you don't really need to use the CRTP idiom for what
you are asking. Probably this does what you want:

Interesting. Thanks Learned after additional searches on Google of a
solution here:
http://stackoverflow.com/questions/8523762/crtp-with-protected-derived-member


Did you mean to say "access *function*"? You cannot overload a function
based on return type, if I understood your question correctly. You will
have to use another strategy. Use two different function names, for example.

Yes, I meant access function. Two different function names as in:

data_access_base<crtp_a>* access1 ( unsigned int xx ) {
if ( xx <= 2) {
data_access_base<crtp_a>* pa = new crtp_a;
return pa ;
}
}

data_access_base<crtp_b>* access2 ( unsigned int xx ) {
if ( xx > 2 ) {
data_access_base<crtp_b>* pb = new crtp_b;
return pb ;
}
}

??
 

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
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top