VC++ Предупреждение C4356: статический член данных не может быть инициализирован через производный класс
Следующий код выдает это предупреждение, но кажется, что оно работает нормально, так как A::st и B::st инициализируются и фактически представляют одну и ту же строку. В моем понимании это некорректный код, который не должен компилироваться (я проверил clang). Интересно, почему VC++ не выдает ошибку вместо предупреждения?
#include <string>
#include <iostream>
class A
{
public:
static const std::string st;
};
class B : public A
{
};
const std::string B::st = "abcd"; //warning C4356: 'A::st': static data member cannot be initialized via derived class
int main()
{
std::cout << A::st << std::endl; // outputs "abcd"
std::cout << B::st << std::endl; // outputs "abcd"
}
1 ответ
Из определения наследования все в порядке, потому что B - это A плюс некоторые дополнительные вещи, но подумайте над тем, что вы определили! Вы определили статическую константную строку в классе a. Поскольку он является статическим, он является глобальным и будет одинаковым для всех экземпляров A и B. Из-за этого даже прямые экземпляры A будут инициализированы с помощью "abcd", и если у вас есть D, который также происходит от A, но не от B он будет содержать abcd, и поскольку он статический, вы не можете определить B, содержащий "abcd", и D, содержащий "efgh". Я не пробовал, но я совершенно уверен, что у вас возникнут некоторые проблемы, если вы определите
clase D :public A
{
};
const std:string d:st = "efgh";
Даже если компилятор сообщает только предупреждение, он, вероятно, зависит от порядка ссылок, каким будет содержимое A::st. это может быть "abcd" или "efgh", но либо d::st будет "abcd", либо B::st будет "efgh", вы не можете определить "abcd" для B и "efgh" для D, потому что это статичен