Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Перегрузка конструктора
Форум на CrossPlatform.RU > Разработка > С\С++
QMainWindow
Привет всем!
Столкнулся с такой проблемой: есть два конструктора класса
Plot2D(int topMargin, int rightMargin, int bottomMargin, int leftMargin, QPaintDevice *paintDevice);
Plot2D(int x, int y, int width, int height, QPaintDevice *paintDevice);
Видно, что в обоих передаваемые типы одинаковы, но по сути это совершенно разные переменные. Компилятор не пожет перегрузить мой конструктор. Как обычно выходят из подобных ситуаций? Добавить какие-то "отличительные" признаки не могу, т.к. они попросту не нужны.
ilyabvt
Цитата
Как обычно выходят из подобных ситуаций?

Меняют объявления конструкторов. Иначе никак.
Цитата
Компилятор не пожет перегрузить мой конструктор.

Я его прекрасно понимаю.
Вот объявление переменной:
Plot2D x(1, 2, 3, 4, image);

Угадайте какой конструктор я использовал?
Алексей1153
class Plot2D
{
    public:
    struct s_margins
    {
        int top___Margin;
        int right_Margin;
        int bottomMargin;
        int left__Margin

        s_margins()
        {
            *this=s_margins(0,0,0,0);
        }

        s_margins
        (
             int top___Margin
            ,int right_Margin
            ,int bottomMargin
            ,int left__Margin
        )
        :top___Margin(top___Margin)
        ,right_Margin(right_Margin)
        ,bottomMargin(bottomMargin)
        ,left__Margin(left__Margin)
        {
        }
    };

    struct s_placements
    {
        int x;
        int x;
        int w;
        int h

        s_placements()
        {
            *this=s_placements(0,0,0,0);
        }

        s_placements
        (
             int x
            ,int y
            ,int w
            ,int h
        )
        :x(x)
        ,y(y)
        ,w(w)
        ,h(h)
        {
        }
    };


    Plot2D(const s_margins& M, QPaintDevice *paintDevice);
    Plot2D(const s_placements& P, QPaintDevice *paintDevice);
}
QMainWindow
Ясно. Или QPaintDevice *paintDevice помять местами в одном...)
Алексей1153
QMainWindow, лучше сразу правильно делать )))
BRE
Цитата(Алексей1153 @ 16.3.2012, 11:28) *
QMainWindow, лучше сразу правильно делать )))

Перед созданием заполнять структуру? Тяжелое наследие виндовс АПИ? ;)
Алексей1153
BRE, апи тут ни при чём. Это во-первых. Во вторых, гораздо быстрее передать один указатель. В-третьих - удобнее, читабельнее и проще модифицировать, когда понадобится добавить ещё переменную :)

а в данном случае это вообще единственный выход

А вызов делать не сложнее:

было
F(x,y,z)

стало
F(s(x,y,z))
Влад
Алексей1153, только вот тут лучше бы иначе:
  struct s_placements
    {
        // ..............
        s_placements()
        :x(0)
        ,y(0)
        ,w(0)
        ,h(0)
        {
        }

    };
или использовать делегирующий конструктор, если компилятор поддерживает C++11:
    struct s_placements
    {

        s_placements() : s_placements(0,0,0,0)
        {
        }

    };
Алексей1153
Влад, да, поленился )

а вот это
Цитата
s_placements() : s_placements(0,0,0,0)

не приветствую!
BRE
Цитата(Алексей1153 @ 16.3.2012, 14:15) *
апи тут ни при чём. Это во-первых.

А что причем? :) Да, язык C++ не может иметь разные конструкторы с одинаковыми сигнатурами, но это же совсем не повод для таких решений.

Цитата(Алексей1153 @ 16.3.2012, 14:15) *
Во вторых, гораздо быстрее передать один указатель.

А время заполнения структуры ты считаешь? А почему?

Цитата(Алексей1153 @ 16.3.2012, 14:15) *
В-третьих - удобнее, читабельнее и проще модифицировать, когда понадобится добавить ещё переменную :)

Читабелнее? Тоже спорно.
F(s(x,y,z))

Читающему код придется разбираться, а что это за s такой? Объект это или функция, что-то возвращающая.

По мне, так вводить отдельную сущность на каждый чих это перебор. Если эту структуру можно выделить в отдельный класс - выделяй, но делать это для передачи параметров... это в лучших традициях "специалистов" микрософта.
Iron Bug
Цитата(Алексей1153 @ 16.3.2012, 17:50) *
а вот это
Цитата
s_placements() : s_placements(0,0,0,0)

не приветствую!

а зря. почитай ответ на вопрос тут (чтобы не писать многабукаф):
http://www.codeguru.com/forum/archive/inde...p/t-179378.html

Алексей1153
BRE, не на каждый чих, а при необходимости же. Например, как в этой теме. Или в коллбэках. Или когдаструктура создаётся один раз, а вызывать метод надо тонну раз либо вообще рекурсивно. Не надо свою любовь к винде смешивать с логикой ;)

Iron Bug, букаф точно много, ткни пальцем ))) А я поясню, почему не поддерживаю - нет имён мемберов. Скатились к чистому С :

struct A
{
   int i1;
   int i2;
   int i3;
};


A a={1,2,3};


и тут программист вдруг решил переставить местами i1 и i3

struct A
{
   int i3;
   int i2;
   int i1;
};


и приехали. А ведь забыть подкорректировать конструктор легко
BRE
Цитата(Алексей1153 @ 16.3.2012, 20:01) *
BRE, не на каждый чих, а при необходимости же.

А если таких конструкторов будет 10 создать 10 структур? А если 20? А потом без постоянного смотрения в документацию или исходники, этим классом воспользоваться будет нельзя?

Цитата(Алексей1153 @ 16.3.2012, 20:01) *
Не надо свою любовь к винде смешивать с логикой ;)

Ну если люди могут сделать жесть, а ты предлагаешь аналогичные решения. ;)

Еще раз о своем отношении к такому подходу, если в терминах предметной области можно/удобно выделить такую структуру в отдельную сущность, то это нужно сделать. А использовать это только для передачи параметров - нет, лучше пересмотреть интерфейс класса.
Алексей1153
Цитата(BRE @ 16.3.2012, 22:12) *
А если таких конструкторов будет 10 создать 10 структур? А если 20? А потом без постоянного смотрения в документацию или исходники, этим классом воспользоваться будет нельзя?

да хоть 40. Ну посмотри на названия моих структур - что, сильно захотелось в документацию полезть ? :)

или как ты хочешь эти 40 вариантов конструкторов разнообразить ?
BRE
Цитата(Алексей1153 @ 16.3.2012, 21:02) *
или как ты хочешь эти 40 вариантов конструкторов разнообразить ?


Цитата
А использовать это только для передачи параметров - нет, лучше пересмотреть интерфейс класса.
Алексей1153
не видю разницы :) . Будет один конструктор и 40 методов настройки
BRE
Цитата(Алексей1153 @ 16.3.2012, 21:53) *
Будет один конструктор и 40 методов настройки

Ну это если не думать. ;) Рекомендую посмотреть на большинство api linux и венды. Очень показательно.
Алексей1153
BRE, ну покажи, чего уж тянуть. Что там такого придумали :)
BRE
Цитата(Алексей1153 @ 17.3.2012, 9:06) *
BRE, ну покажи, чего уж тянуть. Что там такого придумали :)

Так гугол есть. Поищи посмотри, если интересно. ;)
Алексей1153
нет, не особо интересно.
Iron Bug
Цитата(Алексей1153 @ 16.3.2012, 22:01) *
Iron Bug, букаф точно много, ткни пальцем )))

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

а про инициализацию структур - это НЕ конструкторы. читай определение конструктора. у конструктора всегда есть последовательность для инициализации и она строго определена и не зависит от порядка перечисления полей класса. хотя для структур в С++ тоже есть конструкторы, так что никаких проблем нет.
Litkevich Yuriy
я бы стал плясать от сигнатуры функции, насколько сама сигнатура понятна:
Plot2D(int, int, int, int, QPaintDevice *);
В принципе, как стороннему наблюдателю, она мне совершенно не понятна.

Можно воспользоваться советом Алексея, с замечаниями от BRE (использовать некую сущность если она уже широко используется), тем более что это Qt:
вместо второго конструктора использовать такой:
Plot2D(QSize size, QPaintDevice *paintDevice);
инициализировать при этом можно будет так:
Plot2D *plot = new Plot2D(QSize(x, y, w, h), device);


А ещё можно воспользоваться советом Тролей
И ввести дополнительные методы:
Plot2D *plot = new Plot2D(device);
plot->setSize(x, yб w,h);
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.