Имя, скрывающееся в переполнении стека

#include<iostream>

using namespace std;

class ParentClass {
public:
virtual void someFunc(int a){
printf(" ParentClass :: someFunc (int) \n");
};

virtual void someFunc(int* a){
printf(" ParentClass :: someFunc (int*) \n");
};
};

class ChildClass : public ParentClass {
public:
virtual void someFunc(int* a){
printf(" ChildClass ::  someFunc(int*) \n");
};
};

int main(){
ChildClass obj;
/* This function call results in an error: */
obj.someFunc(7);
}

Первый дает ошибку как

tr2.cpp: In function 'int main()':
tr2.cpp:27:19: error: invalid conversion from 'int' to 'int*' [-fpermissive]
obj.someFunc(7);
^
tr2.cpp:18:18: error:   initializing argument 1 of 'virtual void ChildClass::som
eFunc(int*)' [-fpermissive]
virtual void someFunc(int* a){
^

Но если мы изменим метод для принятия char вместо int *, тогда

#include<iostream>

using namespace std;

class ParentClass {
public:
virtual void someFunc(int a){
printf(" ParentClass :: someFunc (int) \n");
};

virtual void someFunc(char a){
printf(" ParentClass :: someFunc (char) \n");
};
};

class ChildClass : public ParentClass {
public:
virtual void someFunc(char a){
cout<<a<<endl;
printf(" ChildClass ::  someFunc(char) \n");
};
};

int main(){
ChildClass obj;
/* This function call results in an error: */
obj.someFunc(7);
}

выход:

 ChildClass ::  someFunc(char)

Со звуком Windows (динь). — ANS: неявное преобразование здесь. Пожалуйста, проверьте редактирование ниже.

Таким образом, скрытие имени работает в первом примере, но не во втором. кто-нибудь может объяснить почему? Я также попытался создать перегруженную переопределенную виртуальную функцию с различным количеством параметров, таких как
int func (int a), int func (int a, int b), а затем переопределяют только один из них. В этом случае также не работает скрытие имен, производный класс может получить виртуальную функцию базового класса, которая не переопределяется.

Почему это имя скрывает работу только в этом конкретном случае?

РЕДАКТИРОВАТЬ 1:

With Context to Eternals Объяснение неявного преобразования. У меня есть другая программа, которая должна быть скрыта от имени, но нет. В этой версии методы дифференцируются на основе разных аргументов.

#include<iostream>

using namespace std;

class ABC
{   public:
ABC()
{
cout<<"Constructor ABC"<<endl;
}
virtual void meth1(int a);
virtual void meth2(int a, int b);
};

void ABC :: meth1(int a)
{
cout<<"One"<<endl;
}

void ABC:: meth2(int a, int b)
{
cout<<"Two"<<endl;
}

class BC:public ABC
{
public:
BC()
{
cout<<"Cons B"<<endl;
}

void meth1(int a);
};

void BC :: meth1(int a)
{
cout<<"Three"<<endl;
}

int main()
{
BC b;
b.meth1(5);
b.meth2(6,7);
}

выход:

C:\Users\Shaurya\Desktop>a
Constructor ABC
Cons B
Three
Two

Скрытие имени в этом случае также не работает.

1

Решение

Когда вы перегружены someFunc() в ChildClassэто скрывает две перегрузки от ParentClass, В первом случае вы вызываете функцию, которая принимает int* как аргумент с целым числом, так что, конечно, он падает, потому что не может выполнить преобразование.

Во втором случае вы вызываете функцию, которая принимает char как аргумент с целым числом, так что есть неявное преобразование, и все в порядке.

Обновление после РЕДАКТИРОВАНИЯ 1:

Я не понимаю, чего вы ожидали:

  • сначала вы строите BC, который является ребенком от ABCтак что есть вызов ABCконструктор тогда BC«s
  • после этого вы звоните meth1(): поскольку BC переопределяет это, BC::meth1() называется
  • наконец ты звонишь meth2(): поскольку BC не отменяет это, ABC::meth2() называется

Единственное «сокрытие имени», которое здесь происходит, это переопределение meth1 BC, но на самом деле это ничего не скрывает …

6

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

В вашем «РЕДАКТИРОВАТЬ 1» имя не скрывается. b.meth2(6,7) не могу найти meth2 в BCтак это выглядит в ABC, Но если вы переименуете meth2 в meth1 везде в программе она не будет компилироваться из-за сокрытия имени: BC::meth1(int) скроет ABC::meth1(int, int),

РЕДАКТИРОВАТЬ: краткое объяснение того, как работает поиск членов класса. Когда компилятор видит object.method(args), где статический тип из object является class Cсначала он ищет функцию-член member в декларации class C, Если он найдет его (или несколько перегрузок), он перестает искать member где-нибудь еще. Если нет, то это выглядит в Cбазовые классы, следуя некоторым загадочным правилам, полностью описанным в стандартной части C ++ 10.2 Member name lookup,

Как только кандидаты найдены, компилятор проверяет, может ли любой из кандидатов быть вызван с заданными аргументами. Если да, и это можно сделать однозначно, функция найдена. В противном случае программа является плохо сформированной. Этот процесс называется разрешение перегрузки и описано частично 13.3 стандарта.

Обратите внимание, что нет слова virtual в приведенном выше объяснении.

2

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