Click here to Skip to main content
15,881,852 members
Please Sign up or sign in to vote.
1.67/5 (2 votes)
See more:
If:
C++
template <class TBase>
class COfficeBorder : public TBase
{
protected:
 
	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
	{
		switch (message)
		{
		case WM_NCPAINT:
			{
				TBase::WindowProc(message, wParam, lParam);
 
				.
				.
				.
 
				return 0; // Handled.
			}
			break;
 
		case WM_CREATE:
			{
				if (TBase::WindowProc(message, wParam, lParam) == -1)
					return -1;
 
				.
				.
				.
 
				return 0; // Handled.
			}
			break;
 
		case WM_NCCALCSIZE:
			{
				LRESULT lResult = TBase::WindowProc(message, wParam, lParam);
 
				.
				.
				.
 
				return lResult;
			}
			break;
		}
 
		return TBase::WindowProc(message, wParam, lParam);
	}
};

is a template class which has been declared without any constructor as you can see.

& I need to extend it by adding the constructor to it.
So this is the extended template class:
C++
template <class TBase>
class COfficeBorderEx : public COfficeBorder<TBase>
{
protected:
 
	COfficeBorderEx(UINT nIDTemplate) : TBase(nIDTemplate)
	{
	}
};


So I don't have to rewrite the COfficeBorder code. only the constructor

The problem in my class, which is a CFormView derived class:

C++
class CMyView : public COfficeBorderEx<CFormView>
{
protected:
    CMyView();
	DECLARE_DYNCREATE(CMyView)

public:
	//{{AFX_DATA(CMyView)
	enum{ IDD = IDD_MYVIEW_FORM };
		// NOTE: the ClassWizard will add data members here
	//}}AFX_DATA

.
.
.
};


Its constructor requires calling the base class constructor as the below:

C++
CMyView::CMyView() : CFormView(CMyView::IDD)
{
    //{{AFX_DATA_INIT(CMyView)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // TODO: add construction code here

}


The problem is when calling CFormView(CMyView::IDD), it calls: COfficeBorderEx(CMyView::IDD), which this last calls: TBase(CMyView::IDD) which is actually: COfficeBorder(CMyView::IDD)

And COfficeBorder Doesn't have a constructor at all.


Is there a possible way for doing this without re-writing the COfficeBorderEx template class from the beginning and embed a constructor to it !?

Thank you for your understanding.
Posted
Updated 7-Jul-13 17:25pm
v4
Comments
Sergey Alexandrovich Kryukov 7-Jul-13 23:09pm    
"Without any default constructor" sounds weird. By definition, such constructor is something which is never explicitly defined. In particular, if you defined no constructors explicitly, it means that the class does have the default constructor. It make your whole question unclear.

Anyway, of course you can derive a template class, and, in particular, add a constructor. Where do you see a problem?
—SA
Mr. Tomay 7-Jul-13 23:40pm    
Sorry, I mean just constructor, not default constructor (Question Improved)
The problem is that CMyView::CMyView() : CFormView(CMyView::IDD) {} invokes COfficeBorder(CMyView::IDD) & COfficeBorder class has no constructor with 1 parameter.
For CFormView: Your derived class must supply its own constructor, see Note
in: http://msdn.microsoft.com/en-us/library/x49xah6k(v=vs.110).aspx
& For CView: Your derived class must not supply its own constructor.

Only for CFormView derived classes I get a compiler error:
error C2512: 'COfficeBorderEx<class cformview="">' : no appropriate default constructor available
Sergey Alexandrovich Kryukov 8-Jul-13 0:35am    
OK, thank you for the clarification/fix, but I still don't understand what prevents you from supplying a constructor you need.
You should also clearly understand the purpose of deriving a class; polymorphism? late binding? what kind of abstraction are you going to use? If you think about it: it all boils down to this.
—SA
Mr. Tomay 8-Jul-13 9:53am    
what prevents me from supplying a constructor I need is that the base template class: COfficeBorder is in a toolkit I have installed as a helper, & I don't need to modify it by supplying a constructor.

I know that declaring a copy template class COfficeBorderEx from COfficeBorder & supply the constructor I need would solve the problem.

But I am wondering If I could just subclass it & just supply the constructor to the derived template class (not to rewrite the entire base template class), because the base class does not have the constructor that I need which has one parameter.
Sergey Alexandrovich Kryukov 8-Jul-13 15:40pm    
Of course you could. If only it makes sense...
—SA

1 solution

The main purpose for this is code compression (write less code.)

instead of writing this (which works very fine):
template <class tbase="">
C++
class COfficeBorderEx : public TBase
{
protected:

	COfficeBorderEx(UINT nIDTemplate) : TBase(nIDTemplate) // This is the constructor which I need.
	{
	}
 
	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
	{
		switch (message)
		{
		case WM_NCPAINT:
			{
				TBase::WindowProc(message, wParam, lParam);
 
				.
				.
				.
 
				return 0; // Handled.
			}
			break;
 
		case WM_CREATE:
			{
				if (TBase::WindowProc(message, wParam, lParam) == -1)
					return -1;
 
				.
				.
				.
 
				return 0; // Handled.
			}
			break;
 
		case WM_NCCALCSIZE:
			{
				LRESULT lResult = TBase::WindowProc(message, wParam, lParam);
 
				.
				.
				.
 
				return lResult;
			}
			break;
		}
 
		return TBase::WindowProc(message, wParam, lParam);
	}
};


I would write just this (which didn't worked for me):

C++
template <class TBase>
class COfficeBorderEx : public COfficeBorder<TBase>
{
protected:
 
	COfficeBorderEx(UINT nIDTemplate) : TBase(nIDTemplate)
	{
	}
};


But I get a compiler error that says:
error C2512: 'COfficeBorderEx' : no appropriate default constructor available

I guess It is not possible :(
 
Share this answer
 
v5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900