переопределение статической функции в случае наследования

class base
{
public:
static void func()
{
cout<<"in base class\n";
}
};

class derived: public base
{
public:
void func()
{
cout<<"In derived class\n";
}
};

main() {
derived d;
d.func();
}

Если я сделаю функцию статической в ​​базовом классе и создаю функцию в производном классе с тем же именем, почему эта функция переопределена, даже если она статическая?

1

Решение

Он не будет переопределен, в противном случае у вас будет ошибка компиляции из-за одного правила определения. У вас есть 2 функции, одна член и одна статическая. d.func() является функцией-членом (как . предлагает). Другая функция base::func(), которая является статической функцией (как :: предлагает).

2

Другие решения

Он не будет переопределен, иначе вы нарушите правило одного определения.

То, что вы видите, это «сфера»:
Если имя определено во внутренней области, оно затеняет (скрывает) все определения того же имени во внешней области.

Вы по-прежнему можете ссылаться на функцию во внешней области видимости (базовый класс) с явной квалификацией:

base::func

Чтобы добавить их из внешней области видимости в набор перегрузки, используйте using-declaration:

using base::func;

Если ты так сделаешь, base::func будет вызываться при использовании derived::func() а также derived::func будет вызываться при использовании derivedobject.func(),

1

Вы испытываете «слежку». То же самое возможно с функциями-членами:

#include <iostream>
struct B {
void func() { std::cout << "in base\n"; }
};

struct D : public B {
void func() { std::cout << "in derived\n"; }
};

int main() {
D d;
d.func();
}

http://ideone.com/kjt2Oa

Это, как предположили другие, называется «затенением», одно определение скрывает другое.

Важно помнить, что вызов статической функции разрешается во время компиляции. Таким образом, следующее будет иметь ожидаемое вами поведение, но это технически неправильное поведение, потому что оно не позволяет вам вызывать самый верхний ‘func’ при использовании указателя базового класса:

void callFunc(base* b) {
b->func();
}

int main() {
derived d;
callFunc(&b);
}

потому что на сайте вызова, b-> указывает на base и позвонил бы base::func вместо derived::func, Во время компиляции все, что знает компилятор, это то, что «b» base,

Большинство людей ожидают и хотят динамичного поведения:

#include <iostream>

struct Animal {
const char* say() { return "???"; }
};

struct Fox : public Animal {
const char* say() { return "A ring ding ding"; }
};

struct Cat : public Animal {
const char* say() { return "Meow"; }
};

void whatDoesItSay(const char* name, Animal* animal) {
std::cout << "The " << name << " says " << animal->say() << ".\n";
}

int main() {
Cat cat;
Fox fox;
whatDoesItSay("cat", &cat);
whatDoesItSay("fox", &fox);
}

http://ideone.com/9wIzq7

Это не имеет желаемого поведения:

Вместо этого нам нужно использовать ключевое слово «virtual» в базовом классе, чтобы указать, что мы хотим полностью полиморфное поведение, и мы можем использовать новое ключевое слово C ++ 11 «override», чтобы убедиться, что мы делаем это:

#include <iostream>

struct Animal {
virtual const char* say() { return "???"; }
};

struct Fox : public Animal {
const char* say() override { return "A ring ding ding"; }
};

struct Cat : public Animal {
const char* say() override { return "Meow"; }
};

void whatDoesItSay(const char* name, Animal* animal) {
std::cout << "The " << name << " says " << animal->say() << ".\n";
}

int main() {
Cat cat;
Fox fox;
whatDoesItSay("cat", &cat);
whatDoesItSay("fox", &fox);
}

http://ideone.com/uOtYMv

1
По вопросам рекламы [email protected]