Ошибка компиляции в VS2010 Ошибка 2259 и LNK 2001 - PullRequest
0 голосов
/ 19 января 2012
class UserParamBase : public UserParamName
{
public:

inline UserParamBase() : m_pParent(NULL), m_bCreate(false), m_bLoad(false),  m_pParentWnd(NULL) {}
inline UserParamBase(const char* name) : UserParamName(name), m_pParent(NULL), m_bCreate(false),  m_pParentWnd(NULL) {}
inline UserParamBase(const UserParamBase&) : m_pParent(NULL), m_bCreate(false),  m_pParentWnd(NULL) {}      //define the copy constructor so as not to use the default
UserParamBase& operator=(const UserParamBase&) { return *this; }    //define the operator= so as not to use the default which would copy a pointer
virtual ~UserParamBase();   
void            attach(UserParamReg* page); 
void            PlaceCtrl(UserParamReg* page, CWnd* pParentWnd, const RECT & r, bool bLoad=true);
void            CreateCtrl()                {create(m_pParentWnd, m_rRegion);};
void            CloseCtrl()                 {close();};
virtual string& value(string& s)        = 0;
virtual bool    load(const string& s)   = 0;
virtual bool    readonly()               =0;        
virtual bool    readonly(bool bReadonly) =0;        
virtual SIZE    winSize()                =0;        
virtual bool    get()                    =0;        
virtual void    update()                 =0;        
virtual void    create(CWnd* pParentWnd,const RECT& rect) =0;   
virtual void    close()                                   =0;

inline bool     loadable() const { return m_bLoad; }

protected:
virtual void    set(bool bAsync=true);

private:

UserParamReg*       m_pParent;
bool                m_bCreate;
bool                m_bLoad;


protected:
RECT                m_rRegion;
CWnd *              m_pParentWnd;
CritSec             m_csWnd;
};

template <class T>
class UserParam : public UserParamB2<T>
{
public:
template <>
class UserParam< string > : public UserParamB2< string >
{
public:
static const LONG   labelHeight             = 16;
static const LONG   controlWidth            = 160;
static const LONG   controlHeightMultiline  = 60;
static const LONG   controlHeightSingleline = 18;
static const LONG   controlWidthFileButton  = 18;
static const bool   defaultMultiline        = true;
static const bool   defaultFileEdit         = false;
static const bool   defaultReadonly         = false;
static const bool   defaultAlignRight       = false;
enum {nIDFileButton=1000, nIDEdit};


inline UserParam() {}
inline UserParam(const type& t,const char* name=NULL)                   : UserParamB2<type>(t,name) {}
inline UserParam(const UserParam& t,const char* name=NULL)              : UserParamB2<type>(t,name) {}
template <class Y> inline UserParam(const Y& y,const char* name=NULL)   : UserParamB2<type>(y,name) {}

inline UserParam& operator=(const UserParam& c) { UserParamB2<type>::operator=(c); return *this; }

bool fileedit(bool bFileEdit) { AutoCritSec acsWnd(m_csWnd, true); return m_wnd.bFileEdit=bFileEdit; }

bool combobox(bool bComboBox=true) { AutoCritSec acsWnd(m_csWnd, true); return m_wnd.bComboBox=bComboBox; }

bool multiline()        { AutoCritSec acsWnd(m_csWnd, true); return m_wnd.bMultiline; }

bool multiline(bool bMultiline) { AutoCritSec acsWnd(m_csWnd, true); return m_wnd.bMultiline=bMultiline; }

void addtolist(string str) { AutoCritSec acsWnd(m_csWnd, true); m_wnd.vSelections.push_back(str); fillcombo();}

inline void alignRight(bool bAlignRight)    { AutoCritSec acsWnd(m_csWnd, true); m_wnd.bAlignRight = bAlignRight; }

inline bool alignRight(){ AutoCritSec acsWnd(m_csWnd, true); return m_wnd.bAlignRight; }

bool readonly()  { AutoCritSec acsWnd(m_csWnd, true); return m_wnd.readonly; }

bool readonly(bool bReadonly)
{
    AutoCritSec acsWnd(m_csWnd, true);
    if(bReadonly==m_wnd.readonly) return m_wnd.readonly;
    if(m_wnd.wnd && m_wnd.wnd->GetSafeHwnd()) {
        if(bReadonly) m_wnd.wnd->PostMessage(WM_CANCELMODE);
        m_wnd.wnd->PostMessage(WM_ENABLE,(WPARAM)!bReadonly);
    }
    return m_wnd.readonly=bReadonly;
}

SIZE winSize() 
{
    SIZE p;
    p.cx=controlWidth;
    p.cy=labelHeight+((m_wnd.bMultiline && !m_wnd.bComboBox)? controlHeightMultiline : controlHeightSingleline);
    return p;
}

//get from control, validate data, set data member if valid;
//return true if data is valid, false otherwise
bool get()
{
    AutoCritSec acsWnd(m_csWnd, true);
    if(m_wnd.combobox && m_wnd.combobox->GetSafeHwnd()) {
        CString text;
        m_wnd.combobox->GetWindowText(text);
        this->assign((LPCSTR) text);

    } else if(m_wnd.wnd && m_wnd.wnd->GetSafeHwnd()) {

        //get value from control, set m_d
        char* psz=NULL;

        unsigned uSize = m_wnd.wnd->GetWindowTextLength()+1;
        try {
            psz=new char[uSize];
            m_wnd.wnd->GetWindowText(psz,uSize);
            s.assign(psz);
        }
        catch(...) {
            if(psz) delete [] psz;
            throw;
        }
        if(psz) delete [] psz;

        //remove '\r' chars; std::remove returns an iterator to the new .end() position
        //use s.erase(..) to erase from this new .end() position through then end of s
        s.erase(std::remove(s.begin(),s.end(),'\r'),s.end());
        this->assign(s);
    } 

    return true;
}

Сообщение об ошибке выглядит следующим образом:

c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparam.h(437): error C2259: 
'user_param::UserParamB2<std::string>' : cannot instantiate abstract class
 due to following members:   

 'bool user_param::UserParamBase::readonly(bool)' : is abstract
 c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(126) : see   
 declaration of 'user_param::UserParamBase::readonly'
 'bool user_param::UserParamBase::readonly(void)' : is abstract

 c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(125) : see 
 declaration of 'user_param::UserParamBase::readonly'
 'SIZE user_param::UserParamBase::winSize(void)' : is abstract

 c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(127) : see  
 declaration of 'user_param::UserParamBase::winSize'
 'bool user_param::UserParamBase::get(void)' : is abstract 

  c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(130) : see  
  declaration of 'user_param::UserParamBase::get'
  'void user_param::UserParamBase::update(void)' : is abstract

  c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(131) : see
  declaration of 'user_param::UserParamBase::update'
  'void user_param::UserParamBase::create(CWnd *,const RECT &)' : is abstract

  c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(132) : see
  declaration  of 'user_param::UserParamBase::create'
  'void user_param::UserParamBase::close(void)' : is abstract

  c:\qc\qc_daq_development\qc\qc_daq\src\hfgui3\userparambase.h(133) : see 
  declaration  of 'user_param::UserParamBase::close'

Когда я пытаюсь переопределить чисто виртуальную функцию с помощью функции переопределения, ошибки не возникает, но в конце я получаю множество ошибок связывания,Пожалуйста, помогите мне решить эту проблему.Спасибо заранее.Если я что-то упустил или что-то кажется неясным, пожалуйста, дайте мне знать.Хотя опять же с VS 2003 такой проблемы нет, это происходит в 2010 году.

1 Ответ

0 голосов
/ 19 января 2012

Функции-члены абстрактного класса предназначены для переопределения в производном классе. Их цель - объявить интерфейс без предоставления его реализации. Поэтому, когда вы видите что-то вроде virtual int foo() = 0; в любом объявлении класса, это означает, что вы должны создать производный класс и предоставить реализацию foo(), чтобы иметь возможность использовать этот класс:

class CBase {
public:
virtual int foo() = 0;
virtual double bar() = 0;
}

class CDerived : public CBase {
public:
virtual int foo();  //no more `= 0` here cause implementation is provided
virtual double bar();
};

int CDerived::foo()
{
     return 0;
}

double CDerived::bar()
{
     return 0.5;
}

int main()
{
    CBase b; //error - abstract class
    CDerived d; //ok
}

Компилятор должен выдать ошибку, если у вас есть virtual int foo() = 0 в вашем CDerived и предоставить определение функции. Тот факт, что VS2003 компилирует такой код, выглядит как проблема соответствия.

Редактировать

В вашем коде больше ошибок.

Для класса, объявленного как:

class UserParamBase : public UserParamName
{
 /*...*/
virtual bool    readonly();
}

определение функции должно быть:

bool UserParamBase::readonly()
{
 /*...*/
}

Странно, что код для readonly () и тому подобное был успешно скомпилирован в вашем случае. Вы определили эти функции как глобальные (или внутри пространства имен), и поэтому они не могли получить доступ к защищенным членам класса, таким как m_csWnd.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...