以下「事件」代碼片段顯示「純虛函數調用」錯誤。但是,正如標題中提到的那樣,只有在DEBUG上部署時纔會發生。令我感到好奇的是,爲什麼它在RELEASE上完美地工作,以及爲什麼它甚至會崩潰(在DEBUG上)。 或者,您可以看到片段here。僅在調試時發生「純虛函數調用」錯誤
#include <list>
#include <iostream>
#include <algorithm>
// use base class to resolve the problem of how to put into collection objects of different types
template <typename TPropertyType>
struct PropertyChangedDelegateBase
{
virtual ~PropertyChangedDelegateBase(){};
virtual void operator()(const TPropertyType& t) = 0;
};
template <typename THandlerOwner, typename TPropertyType>
struct PropertyChangedDelegate : public PropertyChangedDelegateBase<TPropertyType>
{
THandlerOwner* pHandlerOwner_;
typedef void (THandlerOwner::*TPropertyChangeHandler)(const TPropertyType&);
TPropertyChangeHandler handler_;
public:
PropertyChangedDelegate(THandlerOwner* pHandlerOwner, TPropertyChangeHandler handler) :
pHandlerOwner_(pHandlerOwner), handler_(handler){}
void operator()(const TPropertyType& t)
{
(pHandlerOwner_->*handler_)(t);
}
};
template<typename TPropertyType>
class PropertyChangedEvent
{
public:
virtual ~PropertyChangedEvent(){};
void add(PropertyChangedDelegateBase<TPropertyType>* const d)
{
std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = std::find(observers_.begin(), observers_.end(), d);
if(it != observers_.end())
throw std::runtime_error("Observer already registered");
observers_.push_back(d);
}
void remove(PropertyChangedDelegateBase<TPropertyType>* const d)
{
std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = std::find(observers_.begin(), observers_.end(), d);
if(it != observers_.end())
observers_.remove(d);
}
// notify
void operator()(const TPropertyType& newValue)
{
std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = observers_.begin();
for(; it != observers_.end(); ++it)
{
(*it)->operator()(newValue);
}
}
protected:
std::list<PropertyChangedDelegateBase<TPropertyType>* const> observers_;
};
class PropertyOwner
{
int property1_;
float property2_;
public:
PropertyChangedEvent<int> property1ChangedEvent;
PropertyChangedEvent<float> property2ChangedEvent;
PropertyOwner() :
property1_(0),
property2_(0.0f)
{}
int property1() const {return property1_;}
void property1(int n)
{
if(property1_ != n)
{
property1_ = n;
property1ChangedEvent(n);
}
}
float property2() const {return property2_;}
void property2(float n)
{
if(property2_ != n)
{
property2_ = n;
property2ChangedEvent(n);
}
}
};
struct PropertyObserver
{
void OnPropertyChanged(const int& newValue)
{
std::cout << "PropertyObserver::OnPropertyChanged() -> new value is: " << newValue << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
PropertyOwner propertyOwner;
PropertyObserver propertyObserver;
// register observers
PropertyChangedDelegate<PropertyObserver, int> delegate(&propertyObserver, &PropertyObserver::OnPropertyChanged);
propertyOwner.property1ChangedEvent.add(&delegate); // Ok!
propertyOwner.property1ChangedEvent.add(&PropertyChangedDelegate<PropertyObserver, int>(&propertyObserver, &PropertyObserver::OnPropertyChanged)); // Error: Virtual pure function call (Debug only)
propertyOwner.property1(1);
return getchar();
}
'在RELEASE上完美地工作,爲什麼它甚至崩潰(在DEBUG上)'只是發佈版本沒有啓用這個運行時檢查。不會認爲它是完美的。 – Drop
@Drop - 這不是關於運行時檢查 - 純虛擬調用根本不會發生,因爲'vtable'仍然存在。 –
@RudolfsBundulis爲什麼你認爲它在調試版本中「不存在」? – Drop