Member 13508014 Ответов: 1

Перегрузка метода базового класса в производном классе В C++


#include <iostream>

using namespace std;

class B {
public:
	 void foo() { cout << "Inside B::foo()" << endl; }
};

class D :public B {
public:	
	void foo(int i) { cout << "Inside D::foo() and i is " << i << endl; }
};

int main()
{
	D d;
	d.foo();

	return 0;
}


Приведенная выше программа не компилируется с ошибкой 'D::foo': функция не принимает 0 аргументов

Я пытаюсь понять, в чем причина того, что производный класс не получил метод foo() (без аргументов) из базового класса. Каково реальное ограничение или дизайн, для которого C++ не предоставляет метод базового класса в производном классе?

Что я уже пробовал:

Чтение статей. Не уверен, что это единственное место, куда мы можем обратиться для всех возможных вопросов в C++.

[no name]

1

1 Ответов

Рейтинг:
1

OriginalGriff

Декларация foo в D скрывает декларацию в B.
Вам нужно добавить using чтобы "выдвинуть его вперед" как отдельную функцию:

#include <iostream>

using namespace std;

class B {
public:
	 void foo() { cout << "Inside B::foo()" << endl; }
};

class D :public B {
public:	
    using B::foo;
	void foo(int i) { cout << "Inside D::foo() and i is " << i << endl; }
};

int main()
{
	D d;
	d.foo();
	d.foo(666);
	return 0;
}


Member 13508014

Что меня удивляет, так это то, что хотя сигнатура метода foo() отличается в производном классе, почему он должен скрывать метод foo() базового класса.

OriginalGriff

Потому что они не находятся в одной области:
https://docs.microsoft.com/en-us/cpp/cpp/function-overloading?view=vs-2019
Найдите "перегрузка, переопределение и скрытие" и внимательно прочитайте раздел под ним.
Вот почему "использование" существует:
https://docs.microsoft.com/en-us/cpp/cpp/using-declaration?view=vs-2019
Он "перемещает" функции базового класса в область производного класса.

Stefan_Lang

5ед.
Признаюсь, я был в тупике. Я и сам об этом не знал. Я действительно знаю об "использовании", но только когда-либо нуждался в нем в случае наследования ромбовидного узора, чтобы устранить двусмысленность пути наследования.

OriginalGriff

Я думаю, что C++ стал несколько чрезмерно сложным: просто в наши дни там слишком много "вещей", чтобы все так хорошо знали все детали. C# движется в том же направлении - я предвижу новый "упрощенный" язык с лучшими битами обоих, которые появятся через десять лет или около того.

Stefan_Lang

Это правда. Я не очень люблю Java, но концепция ограничения множественного наследования чистыми интерфейсами очень хороша. Я хотел бы, чтобы у C++ тоже было это (конечно, теперь уже слишком поздно) и другие ограничения, чтобы предотвратить усложнение вещей, чем это необходимо.

Развитие современного C++ начиная с C++0x вызывает некоторую надежду, но я все еще жду какого-то прорыва, который мог бы сделать язык более доступным для новых программистов и менее обременительным: ограничение использования необработанных указателей, концепций, лучшая поддержка строк, более четкие правила устранения неоднозначности перегрузки (и менее сложные термины для описания всех этих свойств; - p )

OriginalGriff

Проповедь обращенным, мой друг!

[no name]

1