Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 11:49     Функция, которая позволяет выбрать имплементацию члена класса #1
Код ниже компилируется

Хочется добавить фунцию в мейн , которая бы выбирала имплементацию конструктора 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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.07.2012, 11:49     Функция, которая позволяет выбрать имплементацию члена класса
Посмотрите здесь:

Функции в качестве члена класса C++
Определение члена класса C++
C++ Сам вопрос: почему функция-член одного класса не вызывается из функции-члена другого класса?
C++ Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка
C++ Существует ли функция, которая позволяет отобразить окно поверх других?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
29.07.2012, 12:01     Функция, которая позволяет выбрать имплементацию члена класса #2
Не буду говорить, хорошо это или плохо, но если из принципа... Компилятор не может разобраться, какой из конструкторов выбирать, если у них одинаковая сигнатура, он мысли не читает. Поэтому добавляете какому-то из конструкторов лишний параметр, например:
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  ; 
            }
    }
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 12:06  [ТС]     Функция, которая позволяет выбрать имплементацию члена класса #3
Цитата Сообщение от ~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);
}
Не особо красиво, но издеваться над конструктором копирования по умолчанию тоже некрасиво.


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

Ну тогда смотря как. Если это при разработке туда-сюда переключать, но чтоб был только один вариант из двух, тогда простое решение — условная компиляция. В файле реализации пишем:
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. Тогда если эта строка будет там, то при компиляции выберется вариант с копированием, если нет — с присваиванием.

Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 12:23  [ТС]     Функция, которая позволяет выбрать имплементацию члена класса #5
Цитата Сообщение от ~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~ Посмотреть сообщение
Ааа! (Балда Иванович.)


Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
Нененне оба варианта мне вообще не нужно
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
29.07.2012, 12:57     Функция, которая позволяет выбрать имплементацию члена класса #6
Цитата Сообщение от 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; не забыть
    // и точки (.) позаменять на стрелочки (->)
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
29.07.2012, 14:34     Функция, которая позволяет выбрать имплементацию члена класса #7
Leeto, А на кой фиг это нужно? Нужно всегда по возможности использовать список инициализации.
Leeto
 Аватар для Leeto
7 / 7 / 0
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 14:45  [ТС]     Функция, которая позволяет выбрать имплементацию члена класса #8
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, А на кой фиг это нужно? Нужно всегда по возможности использовать список инициализации.
Мне это надо чтоб показать что если имплементировать конструктор с колон синтексисом то конструктор меньше раз вызывает оператор присвоения

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


типа
Dima::Line MyLine

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

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

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, Он вообще их не вызывает, да. Вообще - зачем показывать то, что написано в любой книге по программированию?)
блин ну тебе все расскажи мож у меня какие то более сложные интересные вещи есть ) просто на таком простом примере можно много что построить... Просто решил спросить мож кто идею подкинет более оптимальную чем я смогу придумать )
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
29.07.2012, 15:06     Функция, которая позволяет выбрать имплементацию члена класса #11
Leeto, Во время выполнения невозможно перекомпилировать что-то, изменить namespace и т.д. Товарищ, который предлагал выше - предложил самый логичный вариант.
Вариант с namespace впринципе аналогичен варианту с наследованием.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.07.2012, 15:16     Функция, которая позволяет выбрать имплементацию члена класса
Еще ссылки по теме:

значение по дефолту члена класса C++
C++ Инициализация константы-члена класса
C++ Инициализация static члена класса

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

Или воспользуйтесь поиском по форуму:
novi4ok
549 / 502 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
29.07.2012, 15:16     Функция, которая позволяет выбрать имплементацию члена класса #12
почему не создать два класса: LineDima + LineSasha? и пусть юзырь выбирает
Yandex
Объявления
29.07.2012, 15:16     Функция, которая позволяет выбрать имплементацию члена класса
Ответ Создать тему
Опции темы

Текущее время: 06:03. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru