C ++ model subclass calling an invalid parent constructor

advertisements

I'm using the wrapper template class of Stroustrup:

template<class T, class Pref, class Suf>
class Wrap {
protected:
    T* p;
    int* owned;
    void incr_owned() { if (owned) ++*owned; }
    void decr_owned() { if (owned && --*owned == 0) { delete p; delete owned; } }

    Pref prefix;
    Suf suffix;
public:
    Wrap(T& x, Pref pr, Suf su)
        :p(&x), owned(0), prefix(pr), suffix(su) { } 

    Wrap(T* pp, Pref pr, Suf su)
        :p(pp), owned(new int(1)), prefix(pr), suffix(su) { } 

    Wrap(const Wrap& a)
        :p(a.p), owned(a.owned), prefix(a.prefix), suffix(a.suffix)
        { incr_owned(); }

I'm subclassing it to create a threadsafe object:

template<class DSP> class DspWrap : public Wrap<DSP, void(*)(), void(*)()> {
protected:
    CriticalSection* criticalSection;

public:
    DspWrap(DSP& x) : Wrap<DSP, void(*)(), void(*)()>(x, &DspWrap::prefix, &DspWrap::suffix) {
    }

    DspWrap(DSP* pp) : Wrap<DSP, void(*)(), void(*)()>(pp, &DspWrap::prefix, &DspWrap::suffix) { //compiler error here
    }

But when in the line creating the object DspWrap<PpmDsp> wrap = DspWrap<PpmDsp>(new PpmDsp()); I get the following error error C2664: 'Wrap<T,Pref,Suf>::Wrap(T &,Pref,Suf)' : cannot convert parameter 1 from 'PpmDsp *' to 'PpmDsp &'

But why is it calling the wrong constructor? There actually IS a constructor for PpmDsp*, so why does it try to call PpmDsp&?

Thanks in advance


I'm not sure what you're trying to do with regards to initializing members to themselves, but you need proper construction parameters for the base class, and the base class members *themselves* aren't the way to do that.

Once i declared two real functions for prefix and suffix the rest works and the base constructor initializes correctly. Since I don't have your definitions of CriticalSection or DSP I somewhat have to fake this sample, but....

#include <iostream>

typedef int CriticalSection;

template<class T, class Pref, class Suf>
class Wrap {
protected:
    T* p;
    int* owned;
    void incr_owned() { if (owned) ++*owned; }
    void decr_owned() { if (owned && --*owned == 0) { delete p; delete owned; } }

    Pref prefix;
    Suf suffix;
public:
    Wrap(T& x, Pref pr, Suf su)
        :p(&x), owned(0), prefix(pr), suffix(su) { }

    Wrap(T* pp, Pref pr, Suf su)
        :p(pp), owned(new int(1)), prefix(pr), suffix(su) { }
};

template<class DSP> class DspWrap : public Wrap<DSP, void(*)(), void(*)()> {
protected:
    CriticalSection* criticalSection;

    // implemenations of these
    static void prefix_fn() {};
    static void suffix_fn() {};

public:
    DspWrap(DSP& x)
        : Wrap<DSP, void(*)(), void(*)()>(x, &prefix_fn, &suffix_fn)
        , criticalSection(new CriticalSection)
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

    DspWrap(DSP* pp)
        : Wrap<DSP, void(*)(), void(*)()>(pp, &prefix_fn, &suffix_fn)
        , criticalSection(new CriticalSection)
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

struct MyDSP { };

int main()
{
    MyDSP dsp;
    DspWrap<MyDSP> wrap1(dsp);

    MyDSP *dsp2 = new MyDSP;
    DspWrap<MyDSP> wrap2(dsp2);
    return 0;
}

Output

DspWrap<MyDSP>::DspWrap(DSP &) [DSP = MyDSP]
DspWrap<MyDSP>::DspWrap(DSP *) [DSP = MyDSP]