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

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

29.07.2012, 11:49. Просмотров 732. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.07.2012, 11:49
Ответы с готовыми решениями:

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

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

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

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

11
~ Эврика! ~
1253 / 1002 / 74
Регистрация: 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  ; 
            }
    }
1
7 / 7 / 3
Регистрация: 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);
}
Не особо красиво, но издеваться над конструктором копирования по умолчанию тоже некрасиво.


Так нет вопрос в другом... мне не надо чтобы компилятор выбирал мне надо что бы юзер выбрал... Другими словами если юзер выбирает имплементрацию с колон синтаксисом, то второй вариант имплементации конструктора блокируется и наоборот
Я наверное как не правильно выразился...
0
~ Эврика! ~
1253 / 1002 / 74
Регистрация: 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. Тогда если эта строка будет там, то при компиляции выберется вариант с копированием, если нет — с присваиванием.

Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
1
7 / 7 / 3
Регистрация: 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~ Посмотреть сообщение
Ааа! (Балда Иванович.)


Если же надо оба варианта одновременно, ну тут решение только одно: два класса, у одного один конструктор, у другого — другой.
Нененне оба варианта мне вообще не нужно
0
~ Эврика! ~
1253 / 1002 / 74
Регистрация: 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; не забыть
    // и точки (.) позаменять на стрелочки (->)
}
1
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
29.07.2012, 14:34 7
Leeto, А на кой фиг это нужно? Нужно всегда по возможности использовать список инициализации.
1
7 / 7 / 3
Регистрация: 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
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
29.07.2012, 14:50 9
Leeto, Он вообще их не вызывает, да. Вообще - зачем показывать то, что написано в любой книге по программированию?)
1
7 / 7 / 3
Регистрация: 23.12.2011
Сообщений: 372
Записей в блоге: 1
29.07.2012, 14:53  [ТС] 10
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Вытащить всю функциональность Line и,например, вариант с копированием в базовый класс, унаследовать от него вариант с присваиванием, по желанию пятки динамически создать нужный вариант, привести его к базовому типу и идти дальше:
[cpp]class Line {
Как продолжении этой идеи можно тупа создать два исходника хед и спипи один назвать ColonLine and OrdinaryLine создать от того и того по объекту и просто кинуть в луп пусть пользователь сам выбирает

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

Добавлено через 1 минуту
Цитата Сообщение от ForEveR Посмотреть сообщение
Leeto, Он вообще их не вызывает, да. Вообще - зачем показывать то, что написано в любой книге по программированию?)
блин ну тебе все расскажи мож у меня какие то более сложные интересные вещи есть ) просто на таком простом примере можно много что построить... Просто решил спросить мож кто идею подкинет более оптимальную чем я смогу придумать )
0
В астрале
Эксперт С++
8022 / 4779 / 654
Регистрация: 24.06.2010
Сообщений: 10,554
29.07.2012, 15:06 11
Leeto, Во время выполнения невозможно перекомпилировать что-то, изменить namespace и т.д. Товарищ, который предлагал выше - предложил самый логичный вариант.
Вариант с namespace впринципе аналогичен варианту с наследованием.
1
554 / 508 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
29.07.2012, 15:16 12
почему не создать два класса: LineDima + LineSasha? и пусть юзырь выбирает
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.07.2012, 15:16

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

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

Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка
Создать конструктор копий и оператор присваивания для класса компьютер и члена класса марка. ...

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

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


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

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

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