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

Наследование(Не вызывается конструктор) - C++

Восстановить пароль Регистрация
 
Lotles
 Аватар для Lotles
1 / 1 / 0
Регистрация: 29.12.2009
Сообщений: 167
07.11.2010, 12:39     Наследование(Не вызывается конструктор) #1
f3=f1+f2;
1) Вызывается Fraction operator+(const Fraction& other)
2) Для возвращенного значения вызывается ProperFraction(const Fraction& src) для инициализации временного объекта (назовем его tmp) типа ProperFraction, но почему то при инициализации не вызывается конструктор ProperFraction, а сразу FloatFraction, почему так ?(Смотрел в отладчике)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdafx.h>
#include "Fraction.h"
using namespace std;
class FloatFraction : public Fraction {
public:
    FloatFraction(){
        set(0, 1);
    }
    FloatFraction(int n, int d){
        set(n, d);
    }
    FloatFraction(int n){
        set(n, 1);
    }
    double get_float(){
      return static_cast<double>(get_num())/get_den();
    }
    FloatFraction(const Fraction& src) {
         set(src.get_num(), src.get_den());     
         printf ("zzzzzzzzz\n");
     }
};
class ProperFraction : public FloatFraction {
public:
    ProperFraction(){
        set(0, 1);
    }
    ProperFraction(int n, int d){
        set(n, d);
    }
    ProperFraction(int n){
        set(n, 1);
    }
    ProperFraction(const Fraction& src){
        set(src.Fraction::get_num(), src.get_den());
    }
    void pr_proper(ostream& os){
            if (get_whole() != 0)
            os << get_whole() << " ";
            os << get_num() << "/" << get_den();
        }
    int get_whole(){
                int n = Fraction::get_num();
                return n / get_den();
        }
    int get_num(){
        int n = Fraction::get_num();
        return n % get_den();
        }
    ProperFraction operator=(const ProperFraction& src){ 
        set(src.num, src.den);
        return *this;
    }
};
int main() {
    _asm int 3;
    ProperFraction f1(1,2),f2(5,6),f3;
    f3=f1+f2;
    cout << "Value of f3 is ";
    f3.pr_proper(cout);
    cout << endl;
    cout << "Float value of is " << f3.get_float() << endl;
    return 0;
}
Fraction.h
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "stdafx.h"
#include "conio.h"
using namespace std;
class Fraction{
    void normalize(){
        if (den == 0 || num == 0) {
        num = 0;
        den = 1;
        }
    }
    int gcf(int a, int b){
        if (a % b == 0)
        return abs(b);
    else
        return gcf(b, a % b);
    }
    int lcm(int a, int b){
        return (a/gcf(a,b)*b);
    }
public:
    int num, den;
    Fraction(){
        set(0, 1);
    }
    Fraction(int n, int d){
        set(n, d);
    }
    Fraction(int n){
        set(n,1);
    }
    Fraction(const Fraction& src){
        set(src.num,src.den);
    }
    void set(int n, int d){
        num = n; den = d; normalize();
    }
    int get_num() const{
        return num;
    }
    int get_den() const{
        return den;
    }
    Fraction add(const Fraction& other){
        Fraction fract;
    int lcd = lcm(den, other.den);
    int quot1 = lcd/den;
    int quot2 = lcd/other.den;
    fract.set(num * quot1 + other.num * quot2, lcd);
    fract.normalize();
    return fract;
    }
    Fraction mult(const Fraction& other){
        Fraction fract;
    fract.set(num * other.num, den * other.den);
    fract.normalize();
    return fract;
    }
    Fraction operator+(const Fraction& other){
        return add(other);
        }
    Fraction operator=(const Fraction& src){
        set(src.num, src.den);
        cout << "6666666666666" << endl;
        return *this;
    }
    Fraction operator*(const Fraction& other){
        return mult(other);
    }   
    friend ostream& operator << (ostream& os, Fraction& fr){
        os << fr.num << "/" << fr.den;
        return os;
    }
};
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 15:29     Наследование(Не вызывается конструктор) #2
Допиши конструкторы следующим образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
FloatFraction() {
    std::cout << "FloatFraction()" << std::endl;
    set(0, 1);
}
  
FloatFraction(int n, int d) {
    std::cout << "FloatFraction(int, int)" << std::endl;
    set(n, d);
}
    
FloatFraction(int n) {
    std::cout << "FloatFraction(int)" << std::endl;
    set(n, 1);
}
Аналогично сделай в классе "ProperFraction" и напиши, что печатается на экран.
Lotles
 Аватар для Lotles
1 / 1 / 0
Регистрация: 29.12.2009
Сообщений: 167
07.11.2010, 15:45  [ТС]     Наследование(Не вызывается конструктор) #3
Fraction()
FloatFraction()
ProperFraction(int n, int d)

Fraction()
FloatFraction()
ProperFraction(int n, int d)


Fraction()
FloatFraction()
ProperFraction()


Fraction()
Fraction()
FloatFraction()

...Результат
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 15:59     Наследование(Не вызывается конструктор) #4
Ну вот, все конструкторы у тебя вызываются по порядку, как и положено.
Lotles
 Аватар для Lotles
1 / 1 / 0
Регистрация: 29.12.2009
Сообщений: 167
07.11.2010, 16:00  [ТС]     Наследование(Не вызывается конструктор) #5
А ProperFraction() в конце вроде еще должен
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 16:03     Наследование(Не вызывается конструктор) #6
Это потому что ты в конструкторе копирования отладочную строку не написал.
Lotles
 Аватар для Lotles
1 / 1 / 0
Регистрация: 29.12.2009
Сообщений: 167
07.11.2010, 16:06  [ТС]     Наследование(Не вызывается конструктор) #7
КК да причем
C++
1
2
3
4
    ProperFraction(){
        cout << "ProperFraction()" << endl;
        set(0, 1);
    }
Должен вызываться
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
07.11.2010, 16:09     Наследование(Не вызывается конструктор) #8
Короче, внимательно пройдись по конструкторам и везде сделай вывод строки, причём, чтобы во всех конструкторах выводились разные строки. Конструктор не может не вызываться.
Lotles
 Аватар для Lotles
1 / 1 / 0
Регистрация: 29.12.2009
Сообщений: 167
07.11.2010, 16:24  [ТС]     Наследование(Не вызывается конструктор) #9
Должен вызываться
C++
1
f3=f1+f2
Сюда возвр Fraction, для этого дел-ся преобр в ProperFraction
вызыв
C++
1
2
3
    ProperFraction(const Fraction& src){
        set(src.Fraction::get_num(), src.get_den());
    }
Создается объект ProperFracton, инициализируется
1)
C++
1
2
3
4
  Fraction(){
        cout << "Fraction()" << endl;
        set(0, 1);
    }
2)
C++
1
2
3
4
FloatFraction(){
    cout << "FloatFraction()" << endl;
    set(0, 1);
    }
3) Должен быть
C++
1
2
3
4
    ProperFraction(){
        cout << "ProperFraction()" << endl;
        set(0, 1);
    }
А вы у себя посмотрите вызывается или нет
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.11.2010, 04:17     Наследование(Не вызывается конструктор)
Еще ссылки по теме:

C++ При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
Конструктор вызывается 2 раза C++
Конструктор по умолчанию вызывается после конструктора инициализации C++

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

Или воспользуйтесь поиском по форуму:
volovzi
266 / 168 / 8
Регистрация: 14.03.2010
Сообщений: 501
08.11.2010, 04:17     Наследование(Не вызывается конструктор) #10
Мне кажется, надо не разбираться в твоём коде, а показать пример, как сделать лучше.
Во-первых, с конструкторами следует работать не так (как нужно см. ниже). Во-вторых, дектруктор базового класса следует делать виртуальным. В-третьих, не нужно писать лишнего (например, переопределять конструктор копирования). В-четвёртых, не надо наследовать там, где это не нужно (вместо производного класса "float_fraction" лучше сделать метод "double_value" в базовом). В-пятых, функции нахождения НОД и НОК не следует делать методами класса "fraction" (кстати, НОК мне даже не пригодилось).

Вот моё видение твоей задачи.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include "xtl_math.h"
 
class fraction {
public:
    fraction () : m_numerator(0), m_denominator(1) {}
    fraction (int numerator, int denominator) : m_numerator(numerator), m_denominator(denominator) { fix(); }
    
    virtual ~fraction () {}
    
    // ---- Арифметика ----------------------------------------------------------------------------
    
    fraction operator + (const fraction & f) const {
        return fraction(m_numerator * f.m_denominator + m_denominator * f.m_numerator, m_denominator * f.m_denominator);
    }
    fraction operator - (const fraction & f) const {
        return fraction(m_numerator * f.m_denominator - m_denominator * f.m_numerator, m_denominator * f.m_denominator);
    }
    fraction operator * (const fraction & f) const {
        return fraction(m_numerator * f.m_numerator, m_denominator * f.m_denominator);
    }
    fraction operator / (const fraction & f) const {
        return fraction(m_numerator * f.m_denominator, m_denominator * f.m_numerator);
    }
    
    fraction operator += (const fraction & f) { return *this = *this + f; }
    fraction operator -= (const fraction & f) { return *this = *this - f; }
    fraction operator *= (const fraction & f) { return *this = *this * f; }
    fraction operator /= (const fraction & f) { return *this = *this / f; }
    
    fraction operator - () { return fraction(-m_numerator, m_denominator); }
    fraction operator + () { return fraction(*this); }
    
    // ---- Доступ --------------------------------------------------------------------------------
    
    double double_value () const { return static_cast<double>(m_numerator) / m_denominator; }
    
    // ---- Ввод-вывод ----------------------------------------------------------------------------
    
    friend std::ostream & operator << (std::ostream & stream, const fraction & fract) {
        if (fract.m_numerator == 0 && fract.m_denominator == 0) stream << "nan";
        else if (fract.m_denominator == 0) stream << "inf";
        else if (fract.m_numerator == 0) stream << "0";
        else if (fract.m_denominator == 1) stream << fract.m_numerator;
        else stream << fract.m_numerator << "/" << fract.m_denominator;
        
        return stream;
    }
    
private:
    void fix () {
        simplify();
        fix_sign();
    }
 
    void simplify () {
        int g_c_d = xtd::gcd(m_numerator, m_denominator);
        
        if (g_c_d != 0) {
            m_numerator /= g_c_d;
            m_denominator /= g_c_d;
        }
    }
    
    void fix_sign () {
        if (m_denominator < 0) {
            m_denominator *= -1;
            m_numerator *= -1;
        }
    }
 
protected:
    int m_numerator;
    int m_denominator;
};
 
class proper_fraction : public fraction {
public:
    proper_fraction () : fraction() {}
    proper_fraction (int n, int d) : fraction(n, d) {}
    
    // Здесь нужно только переопределить вывод.
    friend std::ostream & operator << (std::ostream & stream, const proper_fraction & fract);
};
 
int main (int argc, char * const argv[]) {  
    std::cout << fraction()     << std::endl; // 0
    std::cout << fraction(0, 0) << std::endl; // nan
    std::cout << fraction(1, 0) << std::endl; // inf
    std::cout << fraction(1, 2) << std::endl; // 1/2
    
    std::cout << fraction(3, 7).double_value() << std::endl; // 0.428571
 
    return 0;
}
кусок файла xtl_math.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef _XTL_MATH_H
#define _XTL_MATH_H
 
#include <algorithm>
 
namespace xtd {
 
//!     Наибольший общий делитель (greatest common divisor).
int gcd (int first, int second) {
    if (second == 0) std::swap(first, second);
 
    while (second != 0 && (first %= second)) std::swap(first, second);
    
    return abs(second);
}
 
}
 
#endif
Yandex
Объявления
08.11.2010, 04:17     Наследование(Не вызывается конструктор)
Ответ Создать тему
Опции темы

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