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>?
# 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>?