Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 1
Регистрация: 27.02.2011
Сообщений: 14

Компилятор требует конструктор, принимающий аргументом экземпляр того же класса (не ссылку)

30.09.2015, 20:20. Показов 1092. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.

Проблема такова: имеется ряд нижеприведённых классов (для простоты всё, что навскидку не касается данной проблемы, опущено, а проблемные методы упрощены, ибо проблема возникает только при возврате объекта, а создание происходит нормально -- проверял, изменяя возвращаемое значение на указатель и проверяя создание перед возвратом)

Первый (создающий):
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "B.h"
 
class A
{
 //разные методы и поля
 
 B getB()
 {
     return B();
 }
 
}
Второй (создаваемый):
C++
1
2
3
4
5
6
7
8
class B
{
 //разные методы и поля
 explicit B(); // Здесь и далее реализации конструкторов и присваивания для простоты опущены.
 explicit B(const B& b); //Конструктор копирования был введён больше от отчаяния, по идее он не нужен. Проблему, однако, не исправил
 B& operator=(const B& b); //Оператор присваивания здесь за тем же, что и конструктор копирования
 
}
При компиляции выдаёт ошибку:

C++
1
2
In member function 'B A::getB()':
error: no matching function for call to 'B::B(B)'
Экспериментировал с разными модификаторами: explicit/implicit для конструкторов B, const/volatile для B::getB(). Убирал и возвращал конструктор копирования и оператор присваивания для B. Ошибку это не устранило. Гугл и Яндекс отсутствием результатов показали, что такая ошибка ну ооооочень нетриваальная, поэтому если подскажете хотя бы направление поиска решения, буду тоже несказанно рад

Собственно вопрос: с чего вдруг компилятору мог потребоваться конструктор B такого вида? Ведь передача объекта (не ссылки) того же класса в конструктор -- это само по себе дикий бред. Имеют ли место проблемы в коде или же это какая-то особенность компилятора, например?

Данные о системе:
Linux RHEL6;
компилятор g++ версии 4.4.7 20120313
Среда разработки -- Qt Creator

Быть может, есть критические вещи, о которых следовало упомянуть, но которые для меня неочевидны в такой ситуации. Если потребуются уточнения по коду и системе -- с удовольствием дополню информацию Похожих тем на форуме не нашёл.

Заранее спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.09.2015, 20:20
Ответы с готовыми решениями:

Конструктор, принимающий в качестве аргумента ссылку на объект, всё портит
Друзья! Вот корректный код: class foo { public: foo() { } ...

Конструктор производного класса требует конструктор предка
Выдаёт вот такую вот ошибку: no matching function for call to 'Cube::Cube()' class Cube { protected: int magInt; bool...

Конструктор родительского класса с аргументом
abstract class Animal { private String name; public String getName() { return name; } public Animal (String...

12
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
30.09.2015, 20:31
http://rextester.com/JWTFL89862

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//Title of this code
//g++  4.9.2
 
#include <iostream>
 
 
 
struct B
{
    B(){ std::cout<<"конструктор без аргументов.\n";  }
   
    B(B&& b)
    { 
        std::cout<<"перемещающий конструктор будет оптимизирован."
            " вы не увидите этого сообщения\n"; 
    }
    
    void foo() { std::cout<<"hello, Vespertilio!\n"; }
};
 
 
struct A
{
    B getB()const  { return B(); }
};
 
int main()
{
    std::cout << "Hello, world!\n";
    
    
    auto b = A().getB();
    
    b.foo();
    
}
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
30.09.2015, 20:32
Так попробуйте.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;
 
class B
{
public:
    int x;
};
 
class A
{
public:
    B getB(){return B();}
};
 
 
 
int main() {
    A test;
    cout<<test.getB().x<<endl;
    return 0;
}
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.09.2015, 20:41
Vespertilio, запрет неявного преобразования не при чем. Может конструктора в закрытой секции? У меня всё работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
class B{
public:
explicit B():a(5){};
B(const B &b_):a(b_.a ){};
int a;
};
 
class A{
public: 
B getB(){
return B();
}
};
 
int main() {
A a;
cout<<a.getB().a;//5
    cout<<endl;
system("pause");
return 0;
}
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
30.09.2015, 20:49
Цитата Сообщение от IGPIGP Посмотреть сообщение
запрет неявного преобразования не при чем
именно что он причем.

обратите внимание:
Цитата Сообщение от Vespertilio Посмотреть сообщение
explicit B(const B& b);
и ваш код:
Цитата Сообщение от IGPIGP Посмотреть сообщение
B(const B &b_):a(b_.a ){};
если вы запретите неявное приведение типов,
то ваш код перестанет работать:

http://rextester.com/JDSOVU61290

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
class B{
public:
  explicit B():a(5){};
  explicit B(const B &b_):a(b_.a ){};
  int a;
};
 
class A{
public: 
  B getB(){return B(); }
};
 
int main() {
  A a;
  cout<<a.getB().a;//5
  cout<<endl;
  return 0;
}
source_file.cpp: In member function ‘B A::getB()’:
source_file.cpp:13:21: error: no matching function for call to ‘B::B(B)’
B getB(){return B(); }

конструктор копии не должен быть explicit
2
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
30.09.2015, 20:58
Цитата Сообщение от hoggy Посмотреть сообщение
именно что он причем.
Я имел ввиду конструктор с одним параметром, например. А explisit с конструктором копии не заметил так как в голову не пришло, что это нужно. Поэтому и у меня он не explisit.
0
0 / 0 / 1
Регистрация: 27.02.2011
Сообщений: 14
01.10.2015, 16:36  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
конструктор копии не должен быть explicit
Действительно нашёл где-то, что с explicit следует быть внимательней. Однако в других классах конструкторы копирования тоже объявлены как explicit, при этом проблем они не создают. Да к тому же я и без него пробовал

На данный момент, кстати, ошибка ушла, когда из гита старую версию вытащил (ибо новую потерял, экспериментируя ). В чём проблема была -- по прежнему загадка, так как конструирование совпадало до строчки (с учётом конструкторов копирования). То есть, верно ли я понял, что чаще всего проблема в запрете неявного приведения типов? Тогда почему эта ошибка вылезает не всегда?
0
Эксперт PHP
 Аватар для Kerry_Jr
3106 / 2591 / 1219
Регистрация: 14.05.2014
Сообщений: 7,236
Записей в блоге: 1
01.10.2015, 16:41
Vespertilio, скорее всего в том, что конструкторы класса В находятся в private-секции.
0
0 / 0 / 1
Регистрация: 27.02.2011
Сообщений: 14
01.10.2015, 16:49  [ТС]
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
Vespertilio, скорее всего в том, что конструкторы класса В находятся в private-секции.
Проверил, закрыв все конструкторы. Честно говоря, не уверен, так как в этом случае выдаётся такая ошибка:
C++
1
"B::B() is private"
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
01.10.2015, 17:12
Колдовство 11 не смотрел, ибо не шарю.
Автор: у тебя конструктор копий есть с lvalue аргументом, а вызываешь ты с rvalue аргументом. Создай объект B и потом его возвращай.
1
0 / 0 / 1
Регистрация: 27.02.2011
Сообщений: 14
01.10.2015, 17:18  [ТС]
Цитата Сообщение от Enno Посмотреть сообщение
Автор: у тебя конструктор копий есть с lvalue аргументом, а вызываешь ты с rvalue аргументом. Создай объект B и потом его возвращай.
В этом случае выдавал ошибку отсутствия конструктора с параметром-ссылкой (неконстантной):
C++
1
2
In member function 'B A::getB()':
error: no matching function for call to 'B::B(B&)'
Честно говоря, не понимаю, зачем могут по умолчанию понадобиться в качестве передаваемого при конструировании значения неконстантные ссылки/объекты того же класса. Подозреваю, что тема обширная, поэтому если хотя бы направление поиска будет указано, всё равно буду рад
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
01.10.2015, 17:29
Vespertilio, сними explicit с конструктора копий. И ';' расставь в конце объявления классов. С explicit ты никак не вернёшь, конструктор копий при возврате по значению вызывается неявно.
1
0 / 0 / 1
Регистрация: 27.02.2011
Сообщений: 14
30.11.2015, 19:47  [ТС]
Разобрался с explicit/implicit. Быть может, кому-нибудь из вновь столкнувшихся с подобными трудностями будет полезно.

Explicit при копировании смысла не имеет, так как наличие этого ключевого слова означает, что конструктор должен быть вызван явно, чтобы создать экземпляр класса из заданного аргумента. Например, пусть есть два класса:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
{
    int m_a;
public:
    explicit A(int a) : m_a(a) {}
};
 
class B
{
    int m_b;
public:
    B(int b) : m_b(b) {}
};
, тогда экземпляр класса B можно сконструировать из типа int, а класса A -- нет:

C++
1
2
3
4
5
6
void main()
{
    A instance_of_a_1 = 3; //нельзя
    A instance_of_a_2 = A(3); //можно
    B instance_of_b = 3; // можно
}
Хрестоматийный пример: std::string можно сконструировать из char*, так как он имеет неявный конструктор с параметром char*:
C++
1
2
3
...
std::string s = "abcde";
...
Отсюда при использовании явных конструкторов копирования возникает противоречивая ситуация: получается, мы должны всё время явно вызывать конструктор класса при копировании его экземпляров.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.11.2015, 19:47
Помогаю со студенческими работами здесь

Сравнение класса наследника через конструктор с одним аргументом
#include &lt;iostream&gt; using namespace std; //////////////////////////////// class Counter { protected: unsigned int count; ...

Как получить ссылку на текущий экземпляр класса внутри этого класса?
Как? Чтобы отрабатывал деструктор! и в нем можно было поиметь этот this ... Идея в том, что пишу оболочку под некоторую существующую...

Компилятор не хочет создавать экземпляр класса
И пишет непонятные ошибки. В чем дело? template&lt;class T&gt;//шаблон класса class elem { public: template&lt;class T&gt; friend...

Получить ссылку на экземпляр класса
Всем доброго времени суток!!! Есть вот такие два класса. Class1 { } Class2 { List&lt;Class1&gt; lst = new...

Как передать в метод класса ссылку на экземпляр
Есть класс class Class{ ... } Как передать в метод экземплер класса из которого вызывается этот метод? Пробывал так: class Class{ ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru