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

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

30.09.2015, 20:20. Показов 1071. Ответов 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
9005 / 4706 / 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
9005 / 4706 / 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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru