Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
 Аватар для Leeto
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1

Функция, которая позволяет выбрать имплементацию члена класса

29.07.2012, 11:49. Показов 1324. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Код ниже компилируется

Хочется добавить фунцию в мейн , которая бы выбирала имплементацию конструктора Line class между колон синтаксисом и обычным
Другими словами, чтобы в файле Line_cpp
Функция по заданнаму желаю юзера выбирала между этом кодом

C++
1
2
3
4
5
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint): StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        // StartPoint =  NewStartPoint  ; 
        // EndPoint   =  NewEndPoint  ; 
    }
или вот этим

C++
1
2
3
4
5
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint)//: //StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
         StartPoint =  NewStartPoint  ; 
         EndPoint   =  NewEndPoint  ; 
    }

Line_HPP
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
#ifndef Line_HPP // anti multiply including gates
#define Line_HPP
 
//Line.hpp
#include "Point.hpp"
#include <iostream>
            class Line
            {
            private :               //  declaration of private data members 
    
                Point StartPoint;
                Point EndPoint; 
            public :                // public declaration of data members (in given example haven't ) and member functions 
 
                //----------- Declaration of Constructors -----------//
                Line();
                Line (const Point& NewStartPoint,const Point& NewEndPoint) ; 
                ~Line ();
 
                //----------- Declaration of Operators Overloading the class's members -----------//
                Line& operator = (const Line& ObjLine)      ;                   // Assignment operator.         
 
                //----------- Declaration of Global Ostream << Operator  -----------//
            friend std::ostream& operator<< (std::ostream& out,const Line & ObjLine); 
            }   /*!!!*/ ; /*!!!*/ 
#endif // Line_HPP


Point_HPP
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef Point_HPP // anti multiply including gates
#define Point_HPP
#include <string>
#include <iostream>
#include <sstream>
            class Point
            {   
                private:        //  declaration of private data members 
                double x;       // X coordinate
                double y;       // Y coordinate
                public: // public declaration of data members (in given example haven't ) and member functions 
                    //----------- Declaration of Constructors -----------//
                Point();                                        // Default constructor
                Point(const double newX ,const double newY);                // Constructor 
                ~Point(); // 
                //----------- Declaration of Global Ostream << Operator  -----------//
                friend std::ostream& operator << (std::ostream& out,const Point & ObjPoint); 
            } /*!!!*/ ; /*!!!*/
 
#endif // Point_HPP


Point_hpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//                                                          Point_hpp
#ifndef Point_HPP // anti multiply including gates
#define Point_HPP
#include <string>
#include <iostream>
#include <sstream>
            class Point
            {   
                private:        //  declaration of private data members 
                double x;       // X coordinate
                double y;       // Y coordinate
                public: // public declaration of data members (in given example haven't ) and member functions 
                    //----------- Declaration of Constructors -----------//
                Point();                                        // Default constructor
                Point(const double newX ,const double newY);                // Constructor 
                ~Point(); // 
                //----------- Declaration of Global Ostream << Operator  -----------//
                friend std::ostream& operator << (std::ostream& out,const Point & ObjPoint); 
            } /*!!!*/ ; /*!!!*/
 
#endif // Point_HPP


Line_cpp
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
//                                                  Line_cpp
#include "Line.hpp"
    //----------- Implementation of Constructors -----------//
    Line::Line():StartPoint(0,0), EndPoint(0,0) {}
    Line::Line (const Point& NewStartPoint,const Point& NewEndPoint): StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        // StartPoint =  NewStartPoint  ; 
        // EndPoint   =  NewEndPoint  ; 
    }
    //----------- Implementation of Operators Overloading the class's member -----------//
    Line& Line::operator = (const Line& ObjLine)            // Assignment operator.         
        {
                std::cout << "\n*My assignment LINE operator was called*\n";
 
                StartPoint=ObjLine.StartPoint;
                EndPoint=ObjLine.EndPoint;
 
                    return *this ; 
        }
        //----------- Implementation of GLOBAL friend  << Operator  -----------//
    std::ostream& operator << (std::ostream& out,const Line & ObjLine)
            {
                return out << "P1(" << ObjLine.StartPoint 
                           << " ) , P2(" << ObjLine.EndPoint << ")" ; 
            }


Point_cpp
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
//                                              Point_cpp
 
#include "Point.hpp"
 
 int number_of_point_constructor_calls          = 1 ; 
 int number_of_point_destructor_calls           = 1 ; 
 int number_of_point_assignment_operator_calls  = 1 ; 
 
                    //----------- Implementation of Constructors -----------//
            Point::Point() : x(0) , y(0)                                    // Default constructor (implemented using colon syntax )
                { 
                //  std::cout << "hi my default constructor\n\n\t";
                }                           
            Point::Point(const double newX ,const double newY) : x(newX)  , y(newY)     // Constructor 
                { 
                    std::cout << " My Point constructor was called " << number_of_point_constructor_calls++ << " times " << "\n"; 
                }               
            Point::~Point()                                                             // Destructor
                {
                    std::cout << " My Point destructor was called " << number_of_point_destructor_calls++ << " times " << "\n"; 
                }                                    
            Point& Point::operator =  (const Point& ObjPoint)                       // Assignment operator.             
                {       
            std::cout << " My Point assignment operator was called " << number_of_point_assignment_operator_calls++ << " times " << "\n"; 
                    x=ObjPoint.x, y=ObjPoint.y;
                    return *this;                   // The meaning of *this explained in this example (implementation) see comment out  
                }
            std::ostream& operator << (std::ostream& out,const Point & ObjPoint)
                    {
                        return out << "[" << ObjPoint.x << "," << ObjPoint.y << "]" ; 
                    }


main_cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//                                                  main_cpp
#include <iostream>
#include "Point.hpp"
#include "Line.hpp"
 
int main()
    {
    double some_data_for_x[5] = {.1830 , 1.901 , 191.4, 190.0 , 1895.} ; 
    double some_data_for_y[5] = {1903. , 194.7 , 12.11, 1.969 , .1789} ; 
 
    Point P1 (some_data_for_x[1], some_data_for_y[2]); 
    Point P2 (some_data_for_x[2], some_data_for_y[3]); 
 
    Line l(P1, P2); 
    
    std::cout <<"\n Let's cast the line:  " << l << "\n" ; 
 
    std::cout << std::endl;
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.07.2012, 11:49
Ответы с готовыми решениями:

Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса?
//Щас всё объясню. Так, имеем два класса, в одном я определил функцию-член. Все конструкторы и прочее //опущены для уменьшения кода ...

Существует ли функция, которая позволяет отобразить окно поверх других?
Существует ли функция, которая позволяет отобразить окно поверх других?

Ниже приведена функция sum, которая позволяет получить сумму элементов списка, не равных NIL
Ниже приведена функция sum, которая позволяет получить сумму элементов списка, не равных NIL. К сожалению, эта функция работает не совсем...

11
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
29.07.2012, 12:01
Не буду говорить, хорошо это или плохо, но если из принципа... Компилятор не может разобраться, какой из конструкторов выбирать, если у них одинаковая сигнатура, он мысли не читает. Поэтому добавляете какому-то из конструкторов лишний параметр, например:
C++
1
2
3
4
5
6
7
8
9
10
11
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint): StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        // StartPoint =  NewStartPoint  ; 
        // EndPoint   =  NewEndPoint  ; 
    }
 
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint,int ignore)
    {
         StartPoint =  NewStartPoint  ; 
         EndPoint   =  NewEndPoint  ; 
    }
После этого уже можете как вам там надо писать
C++
1
2
3
4
5
6
7
8
if (левая_пятка)
{
    return new Line(start, end);
}
else
{
    return new Line(start, end, 42);
}
Не особо красиво, но издеваться над конструктором копирования по умолчанию тоже некрасиво.

Как вариант, более приятный на вид:
C++
1
2
3
4
5
6
7
8
9
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint,bool reassign = false)
        : StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        if (reassign)
            {
                StartPoint =  NewStartPoint  ; 
                EndPoint   =  NewEndPoint  ; 
            }
    }
1
 Аватар для Leeto
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 12:06  [ТС]
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Не буду говорить, хорошо это или плохо, но если из принципа... Компилятор не может разобраться, какой из конструкторов выбирать, если у них одинаковая сигнатура, он мысли не читает. Поэтому добавляете какому-то из конструкторов лишний параметр, например:
C++
1
2
3
4
5
6
7
8
9
10
11
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint): StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        // StartPoint =  NewStartPoint  ; 
        // EndPoint   =  NewEndPoint  ; 
    }
 
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint,int ignore)
    {
         StartPoint =  NewStartPoint  ; 
         EndPoint   =  NewEndPoint  ; 
    }
После этого уже можете как вам там надо писать
C++
1
2
3
4
5
6
7
8
if (левая_пятка)
{
    return new Line(start, end);
}
else
{
    return new Line(start, end, 42);
}
Не особо красиво, но издеваться над конструктором копирования по умолчанию тоже некрасиво.


Так нет вопрос в другом... мне не надо чтобы компилятор выбирал мне надо что бы юзер выбрал... Другими словами если юзер выбирает имплементрацию с колон синтаксисом, то второй вариант имплементации конструктора блокируется и наоборот
Я наверное как не правильно выразился...
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
29.07.2012, 12:12
Ааа! (Балда Иванович.)

Ну тогда смотря как. Если это при разработке туда-сюда переключать, но чтоб был только один вариант из двух, тогда простое решение — условная компиляция. В файле реализации пишем:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifdef COLON_SYNTAX_LINE
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint): StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        // StartPoint =  NewStartPoint  ; 
        // EndPoint   =  NewEndPoint  ; 
    }
#else
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint)
    {
         StartPoint =  NewStartPoint  ; 
         EndPoint   =  NewEndPoint  ; 
    }
#endif
а в хедере добавляем-убираем #define COLON_SYNTAX_LINE. Тогда если эта строка будет там, то при компиляции выберется вариант с копированием, если нет — с присваиванием.

Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
1
 Аватар для Leeto
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 12:23  [ТС]
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Ааа! (Балда Иванович.)

Ну тогда смотря как. Если это при разработке туда-сюда переключать, но чтоб был только один вариант из двух, тогда простое решение — условная компиляция. В файле реализации пишем:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifdef COLON_SYNTAX_LINE
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint): StartPoint(NewStartPoint),EndPoint(NewEndPoint)
    {
        // StartPoint =  NewStartPoint  ; 
        // EndPoint   =  NewEndPoint  ; 
    }
#else
Line::Line (const Point& NewStartPoint,const Point& NewEndPoint)
    {
         StartPoint =  NewStartPoint  ; 
         EndPoint   =  NewEndPoint  ; 
    }
#endif
а в хедере добавляем-убираем #define COLON_SYNTAX_LINE. Тогда если эта строка будет там, то при компиляции выберется вариант с копированием, если нет — с присваиванием.

Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
Так нет мне надо чтобы юзер выбирал... Т.е. чтоб в консоле спрашивалось а-ля "выберете реализацию если конол синтакс нажмите 1 .... "

Добавлено через 37 секунд
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Ааа! (Балда Иванович.)


Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
Нененне оба варианта мне вообще не нужно
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
29.07.2012, 12:57
Цитата Сообщение от Leeto Посмотреть сообщение
Так нет мне надо чтобы юзер выбирал... Т.е. чтоб в консоле спрашивалось а-ля "выберете реализацию если конол синтакс нажмите 1 .... "

Нененне оба варианта мне вообще не нужно
Вот это взаимоисключающие вещи. С++ не Лисп, перекомпилировать программу во время выполнения тут, кхм, сложно. Ведь выбирать надо при выполнении программы, а значит она должна или знать оба варианта, или изменять свой код нужным образом. Поэтому вам придётся сделать две реализации, а внутри уже по if (левая_пятка) выбирать нужную. Вытащить всю функциональность Line и,например, вариант с копированием в базовый класс, унаследовать от него вариант с присваиванием, по желанию пятки динамически создать нужный вариант, привести его к базовому типу и идти дальше:
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
class Line {
public:
    Line(const Point& NewStartPoint, const Point& NewEndPoint)
        : StartPoint(NewStartPoint), EndPoint(NewEndPoint) {}
    // ...
protected:
    Point StartPoint, EndPoint;
};
 
class Line_assign : public Line {
    Line_assign(const Point& NewStartPoint, const Point& NewEndPoint)
    {
        StartPoint = NewStartPoint;
        EndPoint = NewEndPoint;
    }
};
 
int main()
{
    //...
    Line *line = NULL;
    if (пятка) {
        line = new Line(/* ... */);
    }
    else {
        line = new Line_assign(/* ... */);
    }
    // дальшё всё как обычно, только delete line; не забыть
    // и точки (.) позаменять на стрелочки (->)
}
1
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.07.2012, 14:34
Leeto, А на кой фиг это нужно? Нужно всегда по возможности использовать список инициализации.
1
 Аватар для Leeto
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 14:45  [ТС]
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, А на кой фиг это нужно? Нужно всегда по возможности использовать список инициализации.
Мне это надо чтоб показать что если имплементировать конструктор с колон синтексисом то конструктор меньше раз вызывает оператор присвоения

Добавлено через 5 минут
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вот это взаимоисключающие вещи. С++ не Лисп, перекомпилировать программу во время выполнения тут, кхм, сложно. Ведь выбирать надо при выполнении программы, а значит она должна или знать оба варианта, или изменять свой код нужным образом. [/cpp]
А может можно как то через namespace попробовать реализовать ? ну типа если 1 то использовать line которую написал дима а если 2 то которую написал саша


типа
Dima::Line MyLine

Sasha::Line MyLine
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.07.2012, 14:50
Leeto, Он вообще их не вызывает, да. Вообще - зачем показывать то, что написано в любой книге по программированию?)
1
 Аватар для Leeto
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 14:53  [ТС]
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вытащить всю функциональность Line и,например, вариант с копированием в базовый класс, унаследовать от него вариант с присваиванием, по желанию пятки динамически создать нужный вариант, привести его к базовому типу и идти дальше:
[cpp]class Line {
Как продолжении этой идеи можно тупа создать два исходника хед и спипи один назвать ColonLine and OrdinaryLine создать от того и того по объекту и просто кинуть в луп пусть пользователь сам выбирает

У меня еще идея... А можно это через Визитера сделать ? бутс Вариант ?

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, Он вообще их не вызывает, да. Вообще - зачем показывать то, что написано в любой книге по программированию?)
блин ну тебе все расскажи мож у меня какие то более сложные интересные вещи есть ) просто на таком простом примере можно много что построить... Просто решил спросить мож кто идею подкинет более оптимальную чем я смогу придумать )
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
29.07.2012, 15:06
Leeto, Во время выполнения невозможно перекомпилировать что-то, изменить namespace и т.д. Товарищ, который предлагал выше - предложил самый логичный вариант.
Вариант с namespace впринципе аналогичен варианту с наследованием.
1
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
29.07.2012, 15:16
почему не создать два класса: LineDima + LineSasha? и пусть юзырь выбирает
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.07.2012, 15:16
Помогаю со студенческими работами здесь

Есть ли такая функция даты SQL которая позволяет вытащить записи по опред году, или месяцу или дню
не используя оператор like

Можно ли сделать поле класса параметром функции-члена этого же класса?
Здраствуйте. ref class MyClass { private: int i, j; array&lt;array&lt;int&gt;^&gt;^ X1; array&lt;array&lt;int&gt;^&gt;^ X2; public: ...

Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка
Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка. Всем огромное спасибо за помощь! |

Необходимо создать класс Java, который представляет карту учебного класса, позволяет определить место для студента, отображает карту класса и ищет зан
Доброго времени суток! Нашёл на сайте тему с такой задачкой, но там никто не ответил :...

Worksheet_Change не позволяет выбрать Range составленный из переменных
Добрый вечер, Прошу подсказать почему вылезает ошибка 1004: При изменении ячейки в диапазоне нахожу: aarow = Target.Row ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru