Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Pavel Rem
11 / 11 / 0
Регистрация: 15.07.2016
Сообщений: 124
#1

вызов конструктора, по указателю на объект - C++

16.02.2017, 03:59. Просмотров 300. Ответов 9
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class qwe
{
public:
    qwe() {}
    qwe(char * name, int a, int b):_name(strdup(name)), _a(a), _b(b) {}
private:
    char * _name;
    int _a;
    int _b;
};
 
void main()
{
    qwe * p = new qwe[10];
 
    for (int i = 10; i--;p++)
    {
        *p("hello", 2, 3); //КАК ЭТО СДЕЛАТЬ???
    }
}
как это сделать?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.02.2017, 03:59
Я подобрал для вас темы с готовыми решениями и ответами на вопрос вызов конструктора, по указателю на объект (C++):

Вызов динамического метода класса по указателю на объект класса - C++
Как это можно сделать? И хотелось бы как можно проще.

при вызове конструктора присваивания надо возвращать ссыль на объект или сам объект. Смысл? Значения нужных полей меняютмся и без этого! - C++
Друзья! Обнаружил пробел в знаниях. Собсно, вопрос в теме. Дополню лишь: поля объекта меняются на нужные значения и безо всякого возврата...

Вызов виртуальной функции по указателю - C++
Суть в том, что преподаватель дал задание на защиту курсовой: вызов по указателю виртуальной функции из ТВР, искал в интернете, наткнулся...

Вызов функции по указателю из класса - C++
Такой расклад. Допустим имеем код: #include <iostream> using namespace std; template <class _Tp> class my_mem_fun_t { ...

Вызов виртуальной функции по нулевому указателю - C++
struct A { int sum1(int a, int b) { return a+b; } virtual int sum2(int a, int b) { return a+b; } }; int main() { ...

Как удалить объект по указателю на базовый класс? - C++
Допустим есть несколько классов: // абстрактный класс - введен для управления наследниками class A{ ... } // рабочий класс...

9
nd2
2820 / 2390 / 851
Регистрация: 29.01.2016
Сообщений: 8,003
16.02.2017, 04:33 #2
C++
1
2
3
4
5
6
    qwe * p = new qwe[10];
    
    for (int i = 0; i < 10; ++i)
    {
        p[i] = qwe("hello", 2, 3); 
    }
C++
1
2
3
4
5
6
    qwe * p = new qwe[10];
    qwe* t = p;
    for (int i = 0; i < 10; ++i, ++t)
    {
        *t = qwe("hello", 2, 3); 
    }
1
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4306 / 2325 / 574
Регистрация: 18.10.2014
Сообщений: 3,963
16.02.2017, 04:47 #3
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Pavel Rem Посмотреть сообщение
как это сделать?
Никак. После new qwe[10] все объекты уже сконструированы конструктором по умолчанию. Второй раз для них вызывать конструктор нельзя.

Поэтому акуратно пишем методы для назначения требуемого значения уже сконструированому объекту. Например, через оператор присваивания. Или еще как.

Пока что в коде корректного оператора прсваивания не написано. И еще много чего не хватает.
1
Croessmah
Ушел
13777 / 8027 / 926
Регистрация: 27.09.2012
Сообщений: 19,770
Записей в блоге: 3
Завершенные тесты: 1
16.02.2017, 05:00 #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
    qwe * p = new qwe[3] {
        {"abc", 4, 8},
        {"def", 2, 4},
        {"ghi", 3, 6},
    };
 
    for (int i = 0; i < 3; ++i)
    {
        std::cout << p[i]._name << " " << p[i]._a << " " << p[i]._b << std::endl;
    }
}
http://rextester.com/KVFW49478
1
Alex5
1120 / 781 / 128
Регистрация: 12.04.2010
Сообщений: 2,007
16.02.2017, 12:05 #5
Pavel Rem, TheCalligrapher, "placement new", "размещающая форма оператора new". При этом только вызывается конструктор для заданного объекта (не происходит выделения новой памяти).

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
class A 
{
    int m_n;
public: 
    A(int n) {
        std::cout << "  constructor A(int n),     parameter :  " << n << " \n";
        std::cout << "  old value of   this->m_n : " << this->m_n << " \n\n";
        m_n = n;
    }
    virtual ~A() { 
    }
};
 
 
int main(void)
{
    A a(123);
    new( &a ) A(456);
 
    A* p = new A( 100 );
    new(p) A(200);
 
    system("pause");
    return 0;
}
constructor A(int n), parameter : 123
old value of this->m_n : -858993460

constructor A(int n), parameter : 456
old value of this->m_n : 123

constructor A(int n), parameter : 100
old value of this->m_n : -842150451

constructor A(int n), parameter : 200
old value of this->m_n : 100
Добавлено через 26 минут
http://ideone.com/uyCEOE
0
rikimaru2013
C++ Game Dev
2471 / 1140 / 241
Регистрация: 30.11.2013
Сообщений: 3,709
16.02.2017, 12:35 #6
Alex5, placement new очень опасная вещь и не везде подойдет и легко встать на грабли

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
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <memory>
using namespace std;
 
class ImageController
{
public:
    ImageController( int a )
    {
        cout << " ImageController( int a )" << endl;
    }
    ~ImageController()
    {
        cout << " ~ImageController()" << endl;
    }
};
 
 
class Foo
{
    std::unique_ptr<ImageController> _a;            // класс-член без констр по умолчанию
public:
    Foo()
        : _a( new ImageController(404) )
    {
        cout << "Foo()" << endl;
    }
 
    Foo( int x ) : Foo()
    {
        cout << " Foo( int x )" << endl;
    }
    ~Foo()
    {
        cout << "~Foo()" << endl;
    }
};
 
int main()
{
    {
        Foo a;
        new ( &a ) Foo( 17 );
    }
    cout << "Hello" << endl;
 
}
1
Alex5
1120 / 781 / 128
Регистрация: 12.04.2010
Сообщений: 2,007
16.02.2017, 13:42 #7
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
не везде подойдет
rikimaru2013, разумеется следует отдавать себе отчет, что произойдет при повторном вызове конструктора. (Еще ведь будут вызваны констукторы базовых классов и конструкторы членов.)

И если это категорически не допустимо, то можно заранее об этом позаботиться. http://ideone.com/kCHuOg
Добавим без определения
C++
1
void *operator new(size_t size, Foo *p);
Или переопределим
C++
1
2
3
4
5
void *operator new(size_t size, Foo *p) 
{ 
    //  освобождение ресурсов
    // или   throw   или еще что-то
}
0
MrGluck
Модератор
Эксперт CЭксперт С++
7800 / 4844 / 754
Регистрация: 29.11.2010
Сообщений: 13,210
16.02.2017, 15:21 #8
ТС-у, скорее всего, нужен вектор
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
#include <iostream>
#include <string>
#include <vector>
 
class qwe
{
public:
    qwe(const std::string &name, const int a, const int b) : m_name(name), m_a(a), m_b(b) {}
    // just for example
    friend std::ostream& operator<< (std::ostream &out, const qwe &q)
    {
        return out << q.m_name << " " << q.m_a << " " << q.m_b;
    }
protected:
    std::string m_name;
    int m_a;
    int m_b;
};
 
int main()
{
    std::vector<qwe> v;
    v.emplace_back("hello", 2, 3);
    v.emplace_back("world", 4, 5);
    for (const auto &q : v)
        std::cout << q << std::endl;
}
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4306 / 2325 / 574
Регистрация: 18.10.2014
Сообщений: 3,963
16.02.2017, 18:22 #9
Цитата Сообщение от Alex5 Посмотреть сообщение
Pavel Rem, TheCalligrapher, "placement new", "размещающая форма оператора new". При этом только вызывается конструктор для заданного объекта (не происходит выделения новой памяти).
Это замечательно, но, еще раз: в общем случае запрещается вызывать конструктор для уже сконструированного объекта. Неважно, каком образом это делается - через placement new или еще как. "Переконструировать по новой" тривиальный объект, такой как int еще можно. А для объекта с нетривиальной деструкцией сначала придется вызвать деструктор, а только потом можно будет вызвать конструктор через placement new.

Добавлено через 4 минуты
Цитата Сообщение от Alex5 Посмотреть сообщение
И если это категорически не допустимо, то можно заранее об этом позаботиться. http://ideone.com/kCHuOg
Ну так это просто запретит делать то, что вы предлагаете в качестве решения. Обратите внимание, что класс ТС очевидно, потребует нетривиальной деструкции, то есть именно для него этот способ придется запретить.
0
Alex5
17.02.2017, 11:35     вызов конструктора, по указателю на объект
  #10

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ну так это просто запретит делать то, что вы предлагаете в качестве решения.
TheCalligrapher, я не утверждаю, что использование замещающего оператора new является всегда допустимым.

"всегда допустимо" - этого я не говорил
"в некоторых случаях допустимо" - мое сообщение №5

И так как в некоторых случаях повторный вызов конструктора вполне допустим, утверждение
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
все объекты уже сконструированы ... Второй раз для них вызывать конструктор нельзя.
является неверным.

0
17.02.2017, 11:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2017, 11:35
Привет! Вот еще темы с ответами:

вызов конструктора - C++
Здарова! Есть допустим класс: class Str { Str(); Str(Str&amp;); Str(char*); };

Вызов конструктора - C++
void main() { std::string stemporary; int itemporary; float ftemporary; float fftemporary; ECM *pECM; for (int i=0;i&lt;4;i++) ...

вызов конструктора - C++
Почему при повторном вызове конструктора выбивает ошибку ?Вот здесь ObjX(INUSE); no match for call to `(aClass) (int&amp;)' #include...

Как узнать, какого типа объект находится по указателю - C++
Есть массив указателей базового класса, нужно узнать какие типы этих объектов. class Shape{ public: ~Shape(){} virtual void...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru