Vì vậy, tôi có một lớp cơ sở trừu tượng không có phương thức trừu tượng. Để thực thi tính trừu tượng, tôi đã tuyên bố trình phá hoại (không tầm thường) là thuần túy ảo:Thừa kế ảo thuần túy, đa thừa kế và C4505
class AbstractClass
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
Điều này xây dựng và hoạt động như mong đợi; đầu ra cho một khối mã mà chỉ đơn giản định nghĩa một thể hiện của ConcreteClass là
AbstractClass::AbstractClass() ConcreteClass::ConcreteClass() ConcreteClass::~ConcreteClass() AbstractClass::~AbstractClass()
Bây giờ, khi tôi có lấy được AbstractClass từ một lớp được sử dụng như một lớp giao diện, bản thân có một (tầm thường) destructor ảo (tinh khiết hoặc không) , nó vẫn hoạt động:
class IAlpha
{
public:
virtual ~IAlpha() = 0 {}
};
class AbstractClass : public IAlpha
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
vấn đề nảy sinh khi tôi cố gắng để thực hiện hai giao diện khác nhau theo cách này:
class IAlpha
{
public:
virtual ~IAlpha() = 0 {}
};
class IBeta
{
public:
virtual ~IBeta() = 0 {}
};
class AbstractClass : public IAlpha, public IBeta
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
tại thời điểm này, khi bu ilding, tôi nhận được cảnh báo sau:
warning C4505: 'AbstractClass::~AbstractClass' : unreferenced local function has been removed
Lạ kỳ, tuy nhiên, đầu ra vẫn hiển thị AbstractClass::~AbstractClass()
được gọi.
Đây có phải là lỗi trong MSVC9 (VS 2008) không? Tôi có thể bỏ qua cảnh báo này một cách an toàn không?
Chỉnh sửa: Tôi đã thử tách các định nghĩa phương thức ảo thuần túy khỏi định nghĩa lớp học, vì rõ ràng cú pháp = 0 {}
không thực sự hợp lệ. Thật không may, C4505 vẫn hiển thị, cho dù tôi có chỉ định inline
hay không.
Vì tôi đã không tìm thấy cách nào để cảnh báo này chỉ cho các phương thức này được bảo vệ. Không phải là một giải pháp lý tưởng, nhưng nó đập rearchitecting phân cấp lớp để có được xung quanh một cảnh báo sai lầm.
Tôi đã thử mã trong liên kết của bạn; nó nhận được cùng một cảnh báo mặc dù, như trước đây, nó hoạt động chính xác khi chạy. – somethingdotjunk