Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.06.2013, 15:09   #1
Voipp
Пользователь
 
Регистрация: 03.08.2009
Сообщений: 32
Счастье перегрузка оператора new

сигнатура оператора new :
Код:
void *operator new(size_t size);
Мне не понятно почему во-первых при стандартном вызове этого оператора
размер size не указывается, и ошибка не вылезает, а во-вторых не преобразуется тип из void* в пользовательский?
Вот что я имею ввиду стандартное использование:
Код:
A* a = new A;
PS а так же не понятно как вызывается нестатический оператор до инициализации самого класса
Voipp вне форума Ответить с цитированием
Старый 27.06.2013, 15:27   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Voipp Посмотреть сообщение
сигнатура оператора new :
Код:
void *operator new(size_t size);
Мне не понятно почему во-первых при стандартном вызове этого оператора
размер size не указывается, и ошибка не вылезает, а во-вторых не преобразуется тип из void* в пользовательский?
Вот что я имею ввиду стандартное использование:
Код:
A* a = new A;
PS а так же не понятно как вызывается нестатический оператор до инициализации самого класса
1. Потому что для operator new размер объекта вычисляется и передается в функцию автоматически.

2. new возвращает void*, который преобразуется к типу целевого указателя

3. operator new не может быть методом класса. Он всегда является статическим, даже если при объявлении в классе, не указанно ключевое слово static
_Bers вне форума Ответить с цитированием
Старый 27.06.2013, 15:28   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ну как таковой просто new не есть вызов функции как всякие strlen(str) и тп.
это особый вызов, и он делает больше работы.

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

Код:
A* a=new A;
раскрывается примерно так(упрощенно):
Код:
A* a=((A*)operator new(sizeof(A)))->constructor A();
думаю так ясно какую часть лишь вы делаете операторм.

PS: долго писал((
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 27.06.2013, 16:06   #4
Voipp
Пользователь
 
Регистрация: 03.08.2009
Сообщений: 32
Печаль

Цитата:
Сообщение от _Bers Посмотреть сообщение
1. Потому что для operator new размер объекта вычисляется и передается в функцию автоматически.

2. new возвращает void*, который преобразуется к типу целевого указателя

3. operator new не может быть методом класса. Он всегда является статическим, даже если при объявлении в классе, не указанно ключевое слово static
вспомните malloc, в нем преобразование к типу необходимо вручную приводить!

PS
Вообще я решал эту задачу:
Код:

Foo f; // ошибка компиляции
Foo *f = new Foo;// Ok !
Вот как я это решил:
Код:

class Foo
{
Foo(){;}
public:
 void* operator new(size_t size)
{
     return char[size];
}
}

main()
{
Foo* f = new Foo;
}
Вылезает тупая ошибка доступа к private члену класса. Что на этот раз не так?
Voipp вне форума Ответить с цитированием
Старый 27.06.2013, 16:21   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

у вас конструктор приватный как бы.
Цитата:
вспомните malloc, в нем преобразование к типу необходимо вручную приводить!
ну да, и дальше что?
только это сишная вещь, ориентированная чисто на выделение памяти.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 27.06.2013, 16:39   #6
Voipp
Пользователь
 
Регистрация: 03.08.2009
Сообщений: 32
Печаль

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
у вас конструктор приватный как бы.
ну да, и дальше что?
только это сишная вещь, ориентированная чисто на выделение памяти.
Вы шутить изволите? Я заметил, что приватный !! Этого и добиваюсь вообще-то. Логично, что инициализировать объект незя, а вот создать указатель на него можно, потому, что оператор new имеет доступ к закрытому конструктору.

PS Может есть другие предложения как решить задачу
Voipp вне форума Ответить с цитированием
Старый 27.06.2013, 17:14   #7
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Voipp Посмотреть сообщение
вспомните malloc, в нем преобразование к типу необходимо вручную приводить!
Ну и что? Вам кажется странным, что operator new, который является частью синтаксиса языка с++ отличается от функции malloc, которая является частью библиотеки языка си?

Цитата:
Сообщение от Voipp Посмотреть сообщение
Вообще я решал эту задачу:
Код:
Foo f; // ошибка компиляции
Foo *f = new Foo;// Ok !
Вот как я это решил:
Код:
class Foo
{
   Foo(){}
   public: void* operator new(size_t size){  return char[size]; }
};

main(){ Foo* f = new Foo; }
Вылезает тупая ошибка доступа к private члену класса. Что на этот раз не так?
Конструктор приватный жеж.

Переопределенный operator new публичный.
Вы можете запускать публичные методы, но не можете запускать приватный.

Публичному методу класса доступны приватные методы этого же класса, поэтому, переопределенный operator new имеет доступ к конструктору своего класса. Поэтому, через operator new вы можете построить объект.

Вообще, переопределение оператора new - очень щекотливая тема.

У программиста должны быть очень веские причины, что бы так сделать.
Ибо это источник трудно обнаружаемых и трудно понимаемых граблей.


В данном случае, остается загадкой, чего именно добивается автор этого маловразумительного кода.

Последний раз редактировалось _Bers; 27.06.2013 в 17:16.
_Bers вне форума Ответить с цитированием
Старый 27.06.2013, 17:21   #8
Voipp
Пользователь
 
Регистрация: 03.08.2009
Сообщений: 32
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
Ну и что? Вам кажется странным, что operator new, который является частью синтаксиса языка с++ отличается от функции malloc, которая является частью библиотеки языка си?



Конструктор приватный жеж.

Переопределенный operator new публичный.
Вы можете запускать публичные методы, но не можете запускать приватный.

Публичному методу класса доступны приватные методы этого же класса, поэтому, переопределенный operator new имеет доступ к конструктору своего класса. Поэтому, через operator new вы можете построить объект.

Вообще, переопределение оператора new - очень щекотливая тема.

У программиста должны быть очень веские причины, что бы так сделать.
Ибо это источник трудно обнаружаемых и трудно понимаемых граблей.


В данном случае, остается загадкой, чего именно добивается автор этого маловразумительного кода.
Да, вы все верно изложили выше. В main происходит вызов оператора new, перегруженного для данного класса. А теперь повторю вопрос: в чем ошибка? Я неверно перегрузил оператор, неверно вызвал?

Вы читать посты выше не пробовали? Попробуйте! Там описана задачка которую надо решить.
Voipp вне форума Ответить с цитированием
Старый 27.06.2013, 17:54   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Voipp Посмотреть сообщение
А теперь повторю вопрос: в чем ошибка? Я неверно перегрузил оператор, неверно вызвал?
А погоди... нет, operator new не запустит приватный конструктор.
Что то я попутал:

Код:
class Foo
{
    Foo(){}
    public:

    void* operator new(size_t size){ return ::new Foo(); }
    int v;
};

int main()
{
    Foo* f = new Foo();

// : error C2248: 'Foo::Foo' : cannot access private member declared in class 'Foo'
    return 0;
}

Цитата:
Сообщение от Voipp Посмотреть сообщение
Вы читать посты выше не пробовали? Попробуйте! Там описана задачка которую надо решить.
Вы не пробовали более ясно излагать свои мысли?
Выше я нигде не вижу никакого описания задачки.
_Bers вне форума Ответить с цитированием
Старый 27.06.2013, 19:58   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от Voipp Посмотреть сообщение
PS Может есть другие предложения как решить задачу
Через публичный статичный метод класса

Код:
class CObject
{
private:
  CObject();
public:
  static CObject* Factory() { return new CObject; }
};
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перегрузка оператора >> Sektr63 Общие вопросы C/C++ 5 19.11.2012 01:51
c# перегрузка оператора * world12_tk Помощь студентам 1 06.05.2012 01:04
перегрузка оператора ++ nhr Общие вопросы C/C++ 1 04.05.2011 23:32
Перегрузка оператора + Jane-sad Помощь студентам 0 05.10.2010 13:52
перегрузка оператора -> alex_alpha Общие вопросы C/C++ 5 23.06.2010 19:07