PIMPL idiom for a pointer to a class in C++










1















I have a working interface for two programs (ProgramA and ProgramB) that I would like to improve decoupling both programs as much as possible. The case that I want to cover is making a call from ProgramA to a class from ProgramB (Compute_Prop) that can only be initialized with some arguments which I do not now in advance. Hence, I use a pointer in the header. Currently, I have something like this:



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
Compute_Prop* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



Then, I try to imitate the PIMPL idiom with the following



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
class PIMPL;
PIMPL* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::PIMPL = Compute_Prop;

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



but the compiler says:



error: expected unqualified-id
Compute::PIMPL = Compute_Prop;
^


I guess that it has something to do with Compute_Prop not having
an empty constructor. I can't come up with something that works. What should I do? Something like a pointer to a pointer, maybe? As a restriction, I cannot modify programB.



Note: As it is probably already clear from above, my understanding of low level C++/C is scarce.



EDIT: I introduced the corrections suggested by @n.m. and @Matthieu Brucher










share|improve this question



















  • 1





    Your member declaration syntax is wrong throughout. You are not supposed to repeat the class name inside the class. So no Compute::Compute(), just Compute(). I have no idea why some compilers accept the syntax you are using, it's totally illegal.

    – n.m.
    Nov 13 '18 at 19:37







  • 3





    You cannot assign types in C++. Once you declare class PIMPL; it expects that there will be a class named PIMPL. Pointer declared as PIMPL* ptr; will always have the type PIMPL of that promised class. Compute::PIMPL = Compute_Prop; is not possible, because PIMPL and Compute_Prop are both immutable types. It won't convert all PIMPLs into Compute_Props.

    – Quimby
    Nov 13 '18 at 19:57







  • 1





    if ( compute != nullptr ) delete compute; compute = nullptr; No!! just delete it, or even better, use std::unique_ptr!!

    – Matthieu Brucher
    Nov 13 '18 at 20:09






  • 1





    Compute::PIMPL is a type, you cannot have this type = value syntax. You need a name. Something like Compute::compute perhaps. Compute::PIMPL Compute::compute = ....

    – n.m.
    Nov 13 '18 at 20:28







  • 1





    yes, delete already does the check, it's a useless redundancy. And if you have problems with using unique_ptr, then it means that you have other things to fix as well, ceuase that's how the pimlp should be handled.

    – Matthieu Brucher
    Nov 14 '18 at 14:00















1















I have a working interface for two programs (ProgramA and ProgramB) that I would like to improve decoupling both programs as much as possible. The case that I want to cover is making a call from ProgramA to a class from ProgramB (Compute_Prop) that can only be initialized with some arguments which I do not now in advance. Hence, I use a pointer in the header. Currently, I have something like this:



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
Compute_Prop* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



Then, I try to imitate the PIMPL idiom with the following



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
class PIMPL;
PIMPL* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::PIMPL = Compute_Prop;

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



but the compiler says:



error: expected unqualified-id
Compute::PIMPL = Compute_Prop;
^


I guess that it has something to do with Compute_Prop not having
an empty constructor. I can't come up with something that works. What should I do? Something like a pointer to a pointer, maybe? As a restriction, I cannot modify programB.



Note: As it is probably already clear from above, my understanding of low level C++/C is scarce.



EDIT: I introduced the corrections suggested by @n.m. and @Matthieu Brucher










share|improve this question



















  • 1





    Your member declaration syntax is wrong throughout. You are not supposed to repeat the class name inside the class. So no Compute::Compute(), just Compute(). I have no idea why some compilers accept the syntax you are using, it's totally illegal.

    – n.m.
    Nov 13 '18 at 19:37







  • 3





    You cannot assign types in C++. Once you declare class PIMPL; it expects that there will be a class named PIMPL. Pointer declared as PIMPL* ptr; will always have the type PIMPL of that promised class. Compute::PIMPL = Compute_Prop; is not possible, because PIMPL and Compute_Prop are both immutable types. It won't convert all PIMPLs into Compute_Props.

    – Quimby
    Nov 13 '18 at 19:57







  • 1





    if ( compute != nullptr ) delete compute; compute = nullptr; No!! just delete it, or even better, use std::unique_ptr!!

    – Matthieu Brucher
    Nov 13 '18 at 20:09






  • 1





    Compute::PIMPL is a type, you cannot have this type = value syntax. You need a name. Something like Compute::compute perhaps. Compute::PIMPL Compute::compute = ....

    – n.m.
    Nov 13 '18 at 20:28







  • 1





    yes, delete already does the check, it's a useless redundancy. And if you have problems with using unique_ptr, then it means that you have other things to fix as well, ceuase that's how the pimlp should be handled.

    – Matthieu Brucher
    Nov 14 '18 at 14:00













1












1








1








I have a working interface for two programs (ProgramA and ProgramB) that I would like to improve decoupling both programs as much as possible. The case that I want to cover is making a call from ProgramA to a class from ProgramB (Compute_Prop) that can only be initialized with some arguments which I do not now in advance. Hence, I use a pointer in the header. Currently, I have something like this:



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
Compute_Prop* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



Then, I try to imitate the PIMPL idiom with the following



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
class PIMPL;
PIMPL* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::PIMPL = Compute_Prop;

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



but the compiler says:



error: expected unqualified-id
Compute::PIMPL = Compute_Prop;
^


I guess that it has something to do with Compute_Prop not having
an empty constructor. I can't come up with something that works. What should I do? Something like a pointer to a pointer, maybe? As a restriction, I cannot modify programB.



Note: As it is probably already clear from above, my understanding of low level C++/C is scarce.



EDIT: I introduced the corrections suggested by @n.m. and @Matthieu Brucher










share|improve this question
















I have a working interface for two programs (ProgramA and ProgramB) that I would like to improve decoupling both programs as much as possible. The case that I want to cover is making a call from ProgramA to a class from ProgramB (Compute_Prop) that can only be initialized with some arguments which I do not now in advance. Hence, I use a pointer in the header. Currently, I have something like this:



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
Compute_Prop* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



Then, I try to imitate the PIMPL idiom with the following



interface.h



#include "programB.h" // loads Compute_Prop

class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
class PIMPL;
PIMPL* compute;
;


interface.cpp



#include "programB.h"
#include "interface.h"

#include "programA.h"

Compute::PIMPL = Compute_Prop;

Compute::Compute() = default;

Compute::~Compute()
delete compute;


Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new Compute_Prop( &data, arg2 );



but the compiler says:



error: expected unqualified-id
Compute::PIMPL = Compute_Prop;
^


I guess that it has something to do with Compute_Prop not having
an empty constructor. I can't come up with something that works. What should I do? Something like a pointer to a pointer, maybe? As a restriction, I cannot modify programB.



Note: As it is probably already clear from above, my understanding of low level C++/C is scarce.



EDIT: I introduced the corrections suggested by @n.m. and @Matthieu Brucher







c++ c++11 pointers pimpl-idiom






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 18 '18 at 21:46







Zythos

















asked Nov 13 '18 at 19:26









ZythosZythos

16118




16118







  • 1





    Your member declaration syntax is wrong throughout. You are not supposed to repeat the class name inside the class. So no Compute::Compute(), just Compute(). I have no idea why some compilers accept the syntax you are using, it's totally illegal.

    – n.m.
    Nov 13 '18 at 19:37







  • 3





    You cannot assign types in C++. Once you declare class PIMPL; it expects that there will be a class named PIMPL. Pointer declared as PIMPL* ptr; will always have the type PIMPL of that promised class. Compute::PIMPL = Compute_Prop; is not possible, because PIMPL and Compute_Prop are both immutable types. It won't convert all PIMPLs into Compute_Props.

    – Quimby
    Nov 13 '18 at 19:57







  • 1





    if ( compute != nullptr ) delete compute; compute = nullptr; No!! just delete it, or even better, use std::unique_ptr!!

    – Matthieu Brucher
    Nov 13 '18 at 20:09






  • 1





    Compute::PIMPL is a type, you cannot have this type = value syntax. You need a name. Something like Compute::compute perhaps. Compute::PIMPL Compute::compute = ....

    – n.m.
    Nov 13 '18 at 20:28







  • 1





    yes, delete already does the check, it's a useless redundancy. And if you have problems with using unique_ptr, then it means that you have other things to fix as well, ceuase that's how the pimlp should be handled.

    – Matthieu Brucher
    Nov 14 '18 at 14:00












  • 1





    Your member declaration syntax is wrong throughout. You are not supposed to repeat the class name inside the class. So no Compute::Compute(), just Compute(). I have no idea why some compilers accept the syntax you are using, it's totally illegal.

    – n.m.
    Nov 13 '18 at 19:37







  • 3





    You cannot assign types in C++. Once you declare class PIMPL; it expects that there will be a class named PIMPL. Pointer declared as PIMPL* ptr; will always have the type PIMPL of that promised class. Compute::PIMPL = Compute_Prop; is not possible, because PIMPL and Compute_Prop are both immutable types. It won't convert all PIMPLs into Compute_Props.

    – Quimby
    Nov 13 '18 at 19:57







  • 1





    if ( compute != nullptr ) delete compute; compute = nullptr; No!! just delete it, or even better, use std::unique_ptr!!

    – Matthieu Brucher
    Nov 13 '18 at 20:09






  • 1





    Compute::PIMPL is a type, you cannot have this type = value syntax. You need a name. Something like Compute::compute perhaps. Compute::PIMPL Compute::compute = ....

    – n.m.
    Nov 13 '18 at 20:28







  • 1





    yes, delete already does the check, it's a useless redundancy. And if you have problems with using unique_ptr, then it means that you have other things to fix as well, ceuase that's how the pimlp should be handled.

    – Matthieu Brucher
    Nov 14 '18 at 14:00







1




1





Your member declaration syntax is wrong throughout. You are not supposed to repeat the class name inside the class. So no Compute::Compute(), just Compute(). I have no idea why some compilers accept the syntax you are using, it's totally illegal.

– n.m.
Nov 13 '18 at 19:37






Your member declaration syntax is wrong throughout. You are not supposed to repeat the class name inside the class. So no Compute::Compute(), just Compute(). I have no idea why some compilers accept the syntax you are using, it's totally illegal.

– n.m.
Nov 13 '18 at 19:37





3




3





You cannot assign types in C++. Once you declare class PIMPL; it expects that there will be a class named PIMPL. Pointer declared as PIMPL* ptr; will always have the type PIMPL of that promised class. Compute::PIMPL = Compute_Prop; is not possible, because PIMPL and Compute_Prop are both immutable types. It won't convert all PIMPLs into Compute_Props.

– Quimby
Nov 13 '18 at 19:57






You cannot assign types in C++. Once you declare class PIMPL; it expects that there will be a class named PIMPL. Pointer declared as PIMPL* ptr; will always have the type PIMPL of that promised class. Compute::PIMPL = Compute_Prop; is not possible, because PIMPL and Compute_Prop are both immutable types. It won't convert all PIMPLs into Compute_Props.

– Quimby
Nov 13 '18 at 19:57





1




1





if ( compute != nullptr ) delete compute; compute = nullptr; No!! just delete it, or even better, use std::unique_ptr!!

– Matthieu Brucher
Nov 13 '18 at 20:09





if ( compute != nullptr ) delete compute; compute = nullptr; No!! just delete it, or even better, use std::unique_ptr!!

– Matthieu Brucher
Nov 13 '18 at 20:09




1




1





Compute::PIMPL is a type, you cannot have this type = value syntax. You need a name. Something like Compute::compute perhaps. Compute::PIMPL Compute::compute = ....

– n.m.
Nov 13 '18 at 20:28






Compute::PIMPL is a type, you cannot have this type = value syntax. You need a name. Something like Compute::compute perhaps. Compute::PIMPL Compute::compute = ....

– n.m.
Nov 13 '18 at 20:28





1




1





yes, delete already does the check, it's a useless redundancy. And if you have problems with using unique_ptr, then it means that you have other things to fix as well, ceuase that's how the pimlp should be handled.

– Matthieu Brucher
Nov 14 '18 at 14:00





yes, delete already does the check, it's a useless redundancy. And if you have problems with using unique_ptr, then it means that you have other things to fix as well, ceuase that's how the pimlp should be handled.

– Matthieu Brucher
Nov 14 '18 at 14:00












2 Answers
2






active

oldest

votes


















1














Your implementation should use an interface (or in fact a class with only abstract methods) as a base class.
You cannot assign types in C++. You can only create typedefs and aliases, like that:



using PIMPLType = Compute_Prop;


However this won't work in your case.
This is how it should be implemented (also with possibility of multiple implementations):



class IImplementation

public:
virtual void saySomething() = 0;
;

class ImplementationA : public IImplementation

public:
virtual void saySomething() override
std::cout << "A";

;
class ImplementationB : public IImplementation

public:
virtual void saySomething() override
std::cout << "B";

;

class Foo
IImplementation *pimpl;
public:
Foo()
: pimpl(new ImplementationA)


~Foo() delete pimpl;

void saySomething()
pimpl->saySomething();

;





share|improve this answer























  • I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

    – Zythos
    Nov 14 '18 at 14:02



















0














I may have come across a simple solution. I post it here so you can judge if it is adequate, or even if it can be improved --- sure. I am convinced that runtime polymorphism is not needed, not even polymorphism. The member variable compute is going to be a pointer to a Compute_Prop type anyway. Then, given that performance is critical here: why running the extra overhead of virtual member functions?



The point here is to reach an implementation that hides the inclusion of Compute_Prop without loosing performance. How? This particular solution uses a templated class and then explicit instantiation. The point is that instantiation can be done in the implementation. Got it from a Fluent C++ blog post. Also, this post has hints for how the implementation should be done. A prototype would be:



interface.h



template <typename T>
class Compute
public:
Compute();
Compute(targ1 arg1, targ2 arg2);
~Compute();
// some methods ...
private:
T* compute; // No need to state that is going to be T:=Compute_Prop
;


interface_impl.h



#include "interface.h" 
#include "programA.h"

template <typename T>
Compute::Compute() = default;

template <typename T>
Compute::~Compute()
delete compute;


template <typename T>
Compute::Compute(arg1, arg2)

// do something ... to get data

compute = new T( &data, arg2 );



interface.cpp



 #include "interface.h"
#include "interface_impl.h"
#include "programA.h"
#include "programB.h" // loads Compute_Prop

int main(int argc, char** argv)

template class Compute<Compute_Prop>;




Another related question that might be useful for those with the same dilemma.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288192%2fpimpl-idiom-for-a-pointer-to-a-class-in-c%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Your implementation should use an interface (or in fact a class with only abstract methods) as a base class.
    You cannot assign types in C++. You can only create typedefs and aliases, like that:



    using PIMPLType = Compute_Prop;


    However this won't work in your case.
    This is how it should be implemented (also with possibility of multiple implementations):



    class IImplementation

    public:
    virtual void saySomething() = 0;
    ;

    class ImplementationA : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "A";

    ;
    class ImplementationB : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "B";

    ;

    class Foo
    IImplementation *pimpl;
    public:
    Foo()
    : pimpl(new ImplementationA)


    ~Foo() delete pimpl;

    void saySomething()
    pimpl->saySomething();

    ;





    share|improve this answer























    • I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

      – Zythos
      Nov 14 '18 at 14:02
















    1














    Your implementation should use an interface (or in fact a class with only abstract methods) as a base class.
    You cannot assign types in C++. You can only create typedefs and aliases, like that:



    using PIMPLType = Compute_Prop;


    However this won't work in your case.
    This is how it should be implemented (also with possibility of multiple implementations):



    class IImplementation

    public:
    virtual void saySomething() = 0;
    ;

    class ImplementationA : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "A";

    ;
    class ImplementationB : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "B";

    ;

    class Foo
    IImplementation *pimpl;
    public:
    Foo()
    : pimpl(new ImplementationA)


    ~Foo() delete pimpl;

    void saySomething()
    pimpl->saySomething();

    ;





    share|improve this answer























    • I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

      – Zythos
      Nov 14 '18 at 14:02














    1












    1








    1







    Your implementation should use an interface (or in fact a class with only abstract methods) as a base class.
    You cannot assign types in C++. You can only create typedefs and aliases, like that:



    using PIMPLType = Compute_Prop;


    However this won't work in your case.
    This is how it should be implemented (also with possibility of multiple implementations):



    class IImplementation

    public:
    virtual void saySomething() = 0;
    ;

    class ImplementationA : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "A";

    ;
    class ImplementationB : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "B";

    ;

    class Foo
    IImplementation *pimpl;
    public:
    Foo()
    : pimpl(new ImplementationA)


    ~Foo() delete pimpl;

    void saySomething()
    pimpl->saySomething();

    ;





    share|improve this answer













    Your implementation should use an interface (or in fact a class with only abstract methods) as a base class.
    You cannot assign types in C++. You can only create typedefs and aliases, like that:



    using PIMPLType = Compute_Prop;


    However this won't work in your case.
    This is how it should be implemented (also with possibility of multiple implementations):



    class IImplementation

    public:
    virtual void saySomething() = 0;
    ;

    class ImplementationA : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "A";

    ;
    class ImplementationB : public IImplementation

    public:
    virtual void saySomething() override
    std::cout << "B";

    ;

    class Foo
    IImplementation *pimpl;
    public:
    Foo()
    : pimpl(new ImplementationA)


    ~Foo() delete pimpl;

    void saySomething()
    pimpl->saySomething();

    ;






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 13 '18 at 20:06









    Poeta KoduPoeta Kodu

    648312




    648312












    • I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

      – Zythos
      Nov 14 '18 at 14:02


















    • I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

      – Zythos
      Nov 14 '18 at 14:02

















    I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

    – Zythos
    Nov 14 '18 at 14:02






    I will investigate how to materialize it. Also, a point of concern is speed, methods of Compute are called millions of times and can take either milliseconds or minutes, hours.

    – Zythos
    Nov 14 '18 at 14:02














    0














    I may have come across a simple solution. I post it here so you can judge if it is adequate, or even if it can be improved --- sure. I am convinced that runtime polymorphism is not needed, not even polymorphism. The member variable compute is going to be a pointer to a Compute_Prop type anyway. Then, given that performance is critical here: why running the extra overhead of virtual member functions?



    The point here is to reach an implementation that hides the inclusion of Compute_Prop without loosing performance. How? This particular solution uses a templated class and then explicit instantiation. The point is that instantiation can be done in the implementation. Got it from a Fluent C++ blog post. Also, this post has hints for how the implementation should be done. A prototype would be:



    interface.h



    template <typename T>
    class Compute
    public:
    Compute();
    Compute(targ1 arg1, targ2 arg2);
    ~Compute();
    // some methods ...
    private:
    T* compute; // No need to state that is going to be T:=Compute_Prop
    ;


    interface_impl.h



    #include "interface.h" 
    #include "programA.h"

    template <typename T>
    Compute::Compute() = default;

    template <typename T>
    Compute::~Compute()
    delete compute;


    template <typename T>
    Compute::Compute(arg1, arg2)

    // do something ... to get data

    compute = new T( &data, arg2 );



    interface.cpp



     #include "interface.h"
    #include "interface_impl.h"
    #include "programA.h"
    #include "programB.h" // loads Compute_Prop

    int main(int argc, char** argv)

    template class Compute<Compute_Prop>;




    Another related question that might be useful for those with the same dilemma.






    share|improve this answer





























      0














      I may have come across a simple solution. I post it here so you can judge if it is adequate, or even if it can be improved --- sure. I am convinced that runtime polymorphism is not needed, not even polymorphism. The member variable compute is going to be a pointer to a Compute_Prop type anyway. Then, given that performance is critical here: why running the extra overhead of virtual member functions?



      The point here is to reach an implementation that hides the inclusion of Compute_Prop without loosing performance. How? This particular solution uses a templated class and then explicit instantiation. The point is that instantiation can be done in the implementation. Got it from a Fluent C++ blog post. Also, this post has hints for how the implementation should be done. A prototype would be:



      interface.h



      template <typename T>
      class Compute
      public:
      Compute();
      Compute(targ1 arg1, targ2 arg2);
      ~Compute();
      // some methods ...
      private:
      T* compute; // No need to state that is going to be T:=Compute_Prop
      ;


      interface_impl.h



      #include "interface.h" 
      #include "programA.h"

      template <typename T>
      Compute::Compute() = default;

      template <typename T>
      Compute::~Compute()
      delete compute;


      template <typename T>
      Compute::Compute(arg1, arg2)

      // do something ... to get data

      compute = new T( &data, arg2 );



      interface.cpp



       #include "interface.h"
      #include "interface_impl.h"
      #include "programA.h"
      #include "programB.h" // loads Compute_Prop

      int main(int argc, char** argv)

      template class Compute<Compute_Prop>;




      Another related question that might be useful for those with the same dilemma.






      share|improve this answer



























        0












        0








        0







        I may have come across a simple solution. I post it here so you can judge if it is adequate, or even if it can be improved --- sure. I am convinced that runtime polymorphism is not needed, not even polymorphism. The member variable compute is going to be a pointer to a Compute_Prop type anyway. Then, given that performance is critical here: why running the extra overhead of virtual member functions?



        The point here is to reach an implementation that hides the inclusion of Compute_Prop without loosing performance. How? This particular solution uses a templated class and then explicit instantiation. The point is that instantiation can be done in the implementation. Got it from a Fluent C++ blog post. Also, this post has hints for how the implementation should be done. A prototype would be:



        interface.h



        template <typename T>
        class Compute
        public:
        Compute();
        Compute(targ1 arg1, targ2 arg2);
        ~Compute();
        // some methods ...
        private:
        T* compute; // No need to state that is going to be T:=Compute_Prop
        ;


        interface_impl.h



        #include "interface.h" 
        #include "programA.h"

        template <typename T>
        Compute::Compute() = default;

        template <typename T>
        Compute::~Compute()
        delete compute;


        template <typename T>
        Compute::Compute(arg1, arg2)

        // do something ... to get data

        compute = new T( &data, arg2 );



        interface.cpp



         #include "interface.h"
        #include "interface_impl.h"
        #include "programA.h"
        #include "programB.h" // loads Compute_Prop

        int main(int argc, char** argv)

        template class Compute<Compute_Prop>;




        Another related question that might be useful for those with the same dilemma.






        share|improve this answer















        I may have come across a simple solution. I post it here so you can judge if it is adequate, or even if it can be improved --- sure. I am convinced that runtime polymorphism is not needed, not even polymorphism. The member variable compute is going to be a pointer to a Compute_Prop type anyway. Then, given that performance is critical here: why running the extra overhead of virtual member functions?



        The point here is to reach an implementation that hides the inclusion of Compute_Prop without loosing performance. How? This particular solution uses a templated class and then explicit instantiation. The point is that instantiation can be done in the implementation. Got it from a Fluent C++ blog post. Also, this post has hints for how the implementation should be done. A prototype would be:



        interface.h



        template <typename T>
        class Compute
        public:
        Compute();
        Compute(targ1 arg1, targ2 arg2);
        ~Compute();
        // some methods ...
        private:
        T* compute; // No need to state that is going to be T:=Compute_Prop
        ;


        interface_impl.h



        #include "interface.h" 
        #include "programA.h"

        template <typename T>
        Compute::Compute() = default;

        template <typename T>
        Compute::~Compute()
        delete compute;


        template <typename T>
        Compute::Compute(arg1, arg2)

        // do something ... to get data

        compute = new T( &data, arg2 );



        interface.cpp



         #include "interface.h"
        #include "interface_impl.h"
        #include "programA.h"
        #include "programB.h" // loads Compute_Prop

        int main(int argc, char** argv)

        template class Compute<Compute_Prop>;




        Another related question that might be useful for those with the same dilemma.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 18 '18 at 11:06

























        answered Nov 18 '18 at 1:07









        ZythosZythos

        16118




        16118



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288192%2fpimpl-idiom-for-a-pointer-to-a-class-in-c%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

            Crossroads (UK TV series)

            ữḛḳṊẴ ẋ,Ẩṙ,ỹḛẪẠứụỿṞṦ,Ṉẍừ,ứ Ị,Ḵ,ṏ ṇỪḎḰṰọửḊ ṾḨḮữẑỶṑỗḮṣṉẃ Ữẩụ,ṓ,ḹẕḪḫỞṿḭ ỒṱṨẁṋṜ ḅẈ ṉ ứṀḱṑỒḵ,ḏ,ḊḖỹẊ Ẻḷổ,ṥ ẔḲẪụḣể Ṱ ḭỏựẶ Ồ Ṩ,ẂḿṡḾồ ỗṗṡịṞẤḵṽẃ ṸḒẄẘ,ủẞẵṦṟầṓế