Wywołanie konstruktora parametrycznego dla typów fundamentalnych

0

Witam moi drodzy,
mam dość banalne pytanie sięgające tym razem fundamentów, a dotyczy ono poniższego zadania:

Dokonaj implementacji klasy Cyfra służącej do reprezentacji cyfry.
ma dysponować konstruktorem parametrycznym przyjmującym cyfrę(wartość liczbowa)
jako parametr, przy czym niepoprawne wartości mają być automatyczne sprowadzane do najbliższej poprawnej

  1. Zastanawiam się jak poprawnie wykonać to zadanie. Mogę definiować dla każdego typu fundamentalnego konstruktor, który robi dokładnie to samo zaokrągla liczbę. Później okazało się ze jak mam 3 konstruktory parametryczne przyjmujące, int, float double, i nagle stworze zmienna long double to kompilator głupieje bo nie ma takiego konstruktora, a on sam nie wie którego z pozostałych trzech ma użyć. wiec później pomyślałem, aby po prostu stworzyć jeden konstruktor z parametrem o najwyższej precyzji double long i jakikolwiek typ nie podam, zostanie wykorzystany tylko ten jeden konstruktor który przyjmuje parametr fundamentalny. Czy to podejście jest poprawne ? Zachodzi to zawsze konwersja do double long, ale za to kodu jest mniej.

  2. Jak to ogólnie jest, ze kompilator widząc jeden konstruktor potrafi wykorzystać go dla typów fundamentalnych? Zachodzi tu jakiś proces dziedziczenia?

class Cyfra
{
	int cyferka;

public:
	Cyfra() {};                      // konstruktor domyslny 
	//Cyfra(int c) { cyferka = c; };  // konstruktor z parametrem
	//Cyfra(float rzeczywista) { cyferka = nearbyint(rzeczywista); };
	//Cyfra(double rzeczywista) { cyferka = nearbyint(rzeczywista); };
	Cyfra(double long rzeczywista) { cyferka = nearbyint(rzeczywista); };

	int pobierz_cyferka() { return cyferka; }
};

void main()
{
	double long a = 2.6;
	Cyfra cyferka = Cyfra(a);
	cout << cyferka.pobierz_cyferka();

	cout << endl;
	system("pause");
}

Pozdrawiam ;).

2
  1. Dlaczego nie zrobisz jednego konstruktora przyjmującego int? I czym jest ten dziwny "konstruktor parametryczny"?
  2. No tego to już kompletnie nie rozumiem. Mając konstruktor z - powiedzmy - long double, jesteś w stanie wywołać go podając jako argument obiekt o typie int i pozwala na to zwykłe rzutowanie int -> long double. Żadnego "procesu dziedziczenia".
2

od razu pakujesz value do int czy tam większego typu całkowitego i styka,

ja bym to zrobił tak

#include <iostream>

#include <algorithm>
#include <fstream>
#include <memory>
#include <set>
#include <vector>

class Digit
{
public:
    template<typename T>
    Digit(T input) :
        value_(input) {}

    void display()
    {
        std::cout << value_ << std::endl;
    }
private:
    int value_;
};

int main()
{
    Digit(3.1411111).display();
    Digit(3.14444444444).display();
    Digit(6).display();
    Digit(3333333).display();

    return 0;
}

https://wandbox.org/permlink/ZPh4V6yUFklGveS5

edit po sugestii @pingwindyktator

0
  1. Dlaczego nie zrobisz jednego konstruktora przyjmującego int? I czym jest ten dziwny "konstruktor parametryczny"?
    Ponieważ niepoprawne wartości maja być sprowadzane do najbliższej poprawnej, w przypadku inta, cześć po przecinku zostanie obcięta, dlatego wykorzystalem tutaj funkcje
nearbyint()

i pozostawiłem konstruktor przyjmujący parametr jako typ zmiennoprzecinkowy
"konstruktor parametryczny" fakt dziwnie brzmi. -> konstruktor przyjmujący parametr ;).
2) masz racje, przekombinowałem.

Ciekawa propozycja z template, choć tutaj tez trzeba bedzie trzeba zaokrąglić, do najbliższej całkowitej ;).

4

No dobra, to ja bym zrobił chyba tak:

class Digit
{
public:
    template <typename Integral>
    Digit(Integral v) : value(std::nearbyint(v)) {
        if (value < 0) value = 0;
        if (value > 9) value = 9;
    }

private:
    int value;
};
0
    if (value < 0) value = 0;
    if (value > 9) value = 9;

no tak w końcu to nie cyfry, nie pomyślałem o tym :D.

Dziękuję wam ładnie za pomoc!

1 użytkowników online, w tym zalogowanych: 0, gości: 1