Явная передача объекта const в конструктор, который принимает ссылку const на полиморфный класс - PullRequest
2 голосов
/ 03 февраля 2010

Я столкнулся с проблемой с моими классами, передав константный объект (полиморфную структуру) явному конструктору, который получает константную ссылку на базовый класс этой полиморфной структуры. Вот пример (это не из моего кода, это для объяснения здесь)

class Base 
{
...
}

class Derived:public Base
{
...
}

class Problem 
{
    Problem(const Base&);
...
}

void myFunction(const Problem& problem) 
{
    ...
}

int main() 
{
    //explicit constructor with non const object
    Derived d;
    Problem no1(d); //this is working fine 
    myFunction(no1);

    //implicit constructor with const object
    Problem no2=Derived(); //this is working fine, debugged and everything called fine
    myFunction(no2);   //is working fine

    //explicit constructor with const object NOT WORKING
    Problem no3(Derived());  //debugger jumps over this line (no compiler error here)
    myFunction(no3);   //this line is NOT COMPILING at all it says that:
    //no matching function for call to myFunction(Problem (&)(Derived))
    //note: candidates are: void MyFunction(const Problem&)
}

Кажется, что он работает нормально со второй версией (явный вызов конструктора для задачи), только если я явным образом приведу объект Derived к его базовому классу Base, например:

Problem(*(Base*)&Derived);

Я не осознаю разницу между недвусмысленным и явным вызовом конструктора класса Problem. Спасибо!

Ответы [ 2 ]

6 голосов
/ 03 февраля 2010

Проблема в том, что вы объявляете не объект, а функцию:

Problem no3(Derived());
// equivalent to:
Problem no3(Derived); // with parameter name omitted

Использование:

Problem no3((Derived()));
// extra parens prevent function-declaration interpretation
// which is otherwise required by the standard (so that the code isn't ambiguous)

Это причуды синтаксиса объявления C, унаследованного от C ++.

Дополнительные примеры:

void f(int(a)); /* same as: */ void f(int a);

void g() {
  void function(int);    // declare function
  void function(int());  // we can declare it again
  void function(int=42); // add default value
  function();            // calls ::function(42) ('function' in the global scope)
}
// 'function' not available here (not declared)

void function(int) {} // definition for declarations inside g above
0 голосов
/ 03 февраля 2010

Для дальнейшего использования, это причуда, известная как самый неприятный анализ , см. Другой поток StackOverflow относительно происхождения этого псевдонима.

...