Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
Pavel Rem
11 / 11 / 2
Регистрация: 15.07.2016
Сообщений: 125
#1

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

16.02.2017, 03:59. Просмотров 860. Ответов 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
Ответы с готовыми решениями:

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

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

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

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

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

9
nd2
2836 / 2403 / 1057
Регистрация: 29.01.2016
Сообщений: 8,042
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Эксперт С++
4424 / 2395 / 664
Регистрация: 18.10.2014
Сообщений: 4,051
16.02.2017, 04:47 #3
Лучший ответ Сообщение было отмечено Pavel Rem как решение

Решение

Цитата Сообщение от Pavel Rem Посмотреть сообщение
как это сделать?
Никак. После new qwe[10] все объекты уже сконструированы конструктором по умолчанию. Второй раз для них вызывать конструктор нельзя.

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

Пока что в коде корректного оператора прсваивания не написано. И еще много чего не хватает.
1
Croessmah
++Ͻ
14500 / 8282 / 1556
Регистрация: 27.09.2012
Сообщений: 20,334
Записей в блоге: 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
1122 / 783 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
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
2472 / 1141 / 348
Регистрация: 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
1122 / 783 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
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Эксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
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Эксперт С++
4424 / 2395 / 664
Регистрация: 18.10.2014
Сообщений: 4,051
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
Привет! Вот еще темы с ответами:

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

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

Вызов конструктора
void main() { std::string stemporary; int itemporary; float ftemporary;...


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

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

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