Przesyłanie oryginalnych zmiennych do klasy

0

Witam,
Mam mały problem z moim programem. Mianowicie w klasie Joiner w konstruktorze przesyłam dwa kontenery, ale niestety przesyłam ich kopię, a nie oryginały.
Czy mógłby mi ktoś pomóc jak przesłać oryginalne zmienne, tak żeby funkcje:

*JoinAtBegin() (dodaje na początek kontener który jest podany jako drugi w konstruktorze do tego pierwszego)

*JoinAtEnd() (dodaje na koniec kontener który jest podany jako drugi w konstruktorze do tego pierwszego)
zmieniały kontenery z funkcji main() , a nie te wewnątrz klasy? Poniżej zamieszczam kod:


#include <iostream>
#include<vector>
#include <list>
#include <deque>
#include <random>
#include <chrono>
#include <iterator>
#include <utility>
using Vector = std::vector<double>;
using List = std::list<double>;


template <typename T, typename L>
class Joiner
{
public:
    Joiner(T& container1, L& container2)
    {
        container1_ = container1;
        container2_ = container2;
    }
    void joinAtBegin()
    {
        auto it = container1_.begin();
        auto it2 = container2_.begin();
        container1_.insert(it, it2, it2 = container2_.end());
    }
    void joinAtEnd()
    {
        auto it = container1_.end();
        auto it2 = container2_.begin();
        container1_.insert(it, it2, it2 = container2_.end());
    }
    void showResults()
    {
        std::cout << "kontener 1 z klasy Joiner: " << container1_.size() << std::endl;
        std::cout << "kontener 2 z klasy Joiner: " << container2_.size() << std::endl;       
    }
private:
    T container1_;
    L container2_;
};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main() {
    Vector v1(1000,1.0),v2(1000,2.0);
    List l1(1000,3.0),l2(1000,4.0);
    Joiner <Vector, Vector > joiner1{v1, v2};
    Joiner <List, List > joiner2{l1, l2};
    Joiner <Vector, List > mixedJoiner{v1, l1};

    std::cout << "joiner1: " << std::endl;
    std::cout << "v1 z funkcji main przed: " << v1.size() << std::endl;
    std::cout << "v2 z funkcji main przed: " << v2.size() << std::endl;
    joiner1.joinAtBegin();
    joiner1.joinAtEnd();
    joiner1.showResults();
    std::cout << "v1 z funkcji main po: " << v1.size() << std::endl;
    std::cout << "v2 z funkcji main po: " << v2.size() << std::endl << std::endl;
    
    std::cout << "joiner2: " << std::endl;
    std::cout << "l1 z funkcji main przed: " << l1.size() << std::endl;
    std::cout << "l2 z funkcji main przed: " << l2.size() << std::endl;
    joiner2.joinAtBegin();
    joiner2.joinAtEnd();
    joiner2.showResults();
    std::cout << "l1 z funkcji main po: " << v1.size() << std::endl;
    std::cout << "l2 z funkcji main po: " << v2.size() << std::endl << std::endl;
    
    std::cout << "mixedjoiner: " << std::endl;
    std::cout << "l1 z funkcji main przed: " << l1.size() << std::endl;
    std::cout << "l2 z funkcji main przed: " << l2.size() << std::endl;
    mixedJoiner.joinAtBegin();
    mixedJoiner.joinAtEnd();
    mixedJoiner.showResults();
    std::cout << "l1 z funkcji main przed: " << l1.size() << std::endl;
    std::cout << "l2 z funkcji main przed: " << l2.size() << std::endl;
    return 0;
}

po wywołaniu programu otrzymuję taki wynik (zdjęcie w załączniku)

Czyli w funkcjach JoinAtBegin() i JoinAtEnd() wielkość wektorów się zwiększa, ale kontenery z funkcji main pozostają bez zmiany(nadal mają 1000 elementów), a chcę żeby właśnie te kontenery z maina się zmieniały.
Z góry dziękuję za odpowiedź. Pozdrawiam

1

Pewnie ci chodzi o:

private:
    T & container1_;
    L & container2_;

I być moze konstruktor będzie musiał być formalnie przepisany

0

wtedy wyskakuję masa błędów:

main.cpp:61:5: error: constructor for 'Joiner<std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> > >' must explicitly initialize the reference member 'container1_'
    Joiner(T& container1, L& container2)
    ^
main.cpp:118:30: note: in instantiation of member function 'Joiner<std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> > >::Joiner' requested here
    Joiner <Vector, Vector > joiner1{v1, v2};
                             ^
main.cpp:108:8: note: declared here
    T& container1_;
       ^
main.cpp:61:5: error: constructor for 'Joiner<std::vector<double, std::allocator<double> >, std::vector<double, std::allocator<double> > >' must explicitly initialize the reference member 'container2_'
    Joiner(T& container1, L& container2)
    ^
main.cpp:109:8: note: declared here
    L& container2_;
       ^
main.cpp:61:5: error: constructor for 'Joiner<std::__cxx11::list<double, std::allocator<double> >, std::__cxx11::list<double, std::allocator<double> > >' must explicitly initialize the reference member 'container1_'
    Joiner(T& container1, L& container2)
    ^
main.cpp:119:26: note: in instantiation of member function 'Joiner<std::__cxx11::list<double, std::allocator<double> >, std::__cxx11::list<double, std::allocator<double> > >::Joiner' requested here
    Joiner <List, List > joiner2{l1, l2};
                         ^
main.cpp:108:8: note: declared here
    T& container1_;
       ^
main.cpp:61:5: error: constructor for 'Joiner<std::__cxx11::list<double, std::allocator<double> >, std::__cxx11::list<double, std::allocator<double> > >' must explicitly initialize the reference member 'container2_'
    Joiner(T& container1, L& container2)
    ^
main.cpp:109:8: note: declared here
    L& container2_;
       ^
main.cpp:61:5: error: constructor for 'Joiner<std::vector<double, std::allocator<double> >, std::__cxx11::list<double, std::allocator<double> > >' must explicitly initialize the reference member 'container1_'
    Joiner(T& container1, L& container2)
    ^
main.cpp:120:28: note: in instantiation of member function 'Joiner<std::vector<double, std::allocator<double> >, std::__cxx11::list<double, std::allocator<double> > >::Joiner' requested here
    Joiner <Vector, List > mixedJoiner{v1, l1};
                           ^
main.cpp:108:8: note: declared here
    T& container1_;
       ^
main.cpp:61:5: error: constructor for 'Joiner<std::vector<double, std::allocator<double> >, std::__cxx11::list<double, std::allocator<double> > >' must explicitly initialize the reference member 'container2_'
    Joiner(T& container1, L& container2)
    ^
main.cpp:109:8: note: declared here
    L& container2_;
2

Dla mnie tak klasa nic nie robi. Ja bym ja bym ją skasował bez mrugnięcia okiem.

1

*must explicitly initialize the reference member 'container1_' *
się tłumaczy, jak już wspominałem:

  Joiner(T& container1, L& container2) :   container1_(container1),    container2_ (container2)
    {
    }

To nie twój kod?

MarekR22 napisał(a):

Dla mnie tak klasa nic nie robi. Ja bym ja bym ją skasował bez mrugnięcia okiem.

Za bardzo jestem zmęczony by podjąć ten wątek

0
MarekR22 napisał(a):

Dla mnie tak klasa nic nie robi. Ja bym ja bym ją skasował bez mrugnięcia okiem.

Dlaczego?
dodaje kontenery, bo sprawdzałem?

0
AnyKtokolwiek napisał(a):
  • must explicitly initialize the reference member 'container1_' *
    się tłumaczy, jak już wspominałem:
  Joiner(T& container1, L& container2) :   container1_(container1),    container2_ (container2)
    {
    }

To nie twój kod?

Mój, sam pisałem...

MarekR22 napisał(a):

Dla mnie tak klasa nic nie robi. Ja bym ja bym ją skasował bez mrugnięcia okiem.

Za bardzo jestem zmęczony by podjąć ten wątek

0
AnyKtokolwiek napisał(a):

*must explicitly initialize the reference member 'container1_' *
się tłumaczy, jak już wspominałem:

  Joiner(T& container1, L& container2) :   container1_(container1),    container2_ (container2)
    {
    }

To nie twój kod?

MarekR22 napisał(a):

Dla mnie tak klasa nic nie robi. Ja bym ja bym ją skasował bez mrugnięcia okiem.

Za bardzo jestem zmęczony by podjąć ten wątek

Dobra dziękuję, zmiana konstruktora na ten od "AnyKtokolwiek" rozwiązała problem.
dziękuję wszystkim :)

0

Działa, jak należy

0

a, tak z ciekawości, dlaczego nie można zdefiniować konstruktora tak, jak wcześniej zdefiniowałem?

2
Zdzisław Puchaty napisał(a):

a, tak z ciekawości, dlaczego nie można zdefiniować konstruktora tak, jak wcześniej zdefiniowałem?

Zmienne referencyjna w C++ nie może być ani mikrosekundy nie-zainicjowana, czyli bardziej ściślej musi byś zainicjowana z chwilą tworzenia.
Twój sposób - obrazowo mówiąc - robi to minimalnie później.

Oczywiście istnieje wyjaśnienie bardziej formalne, oparte na standardach itd.

0
AnyKtokolwiek napisał(a):
Zdzisław Puchaty napisał(a):

a, tak z ciekawości, dlaczego nie można zdefiniować konstruktora tak, jak wcześniej zdefiniowałem?

Zmienne referencyjna w C++ nie może być ani mikrosekundy nie-zainicjowana, czyli bardziej ściślej musi byś zainicjowana z chwilą tworzenia.
Twój sposób - obrazowo mówiąc - robi to minimalnie później.

Oczywiście istnieje wyjaśnienie bardziej formalne, oparte na standardach itd.

Ok, rozumiem
Jeszcze raz, Wielkie dzięki

1
Zdzisław Puchaty napisał(a):
MarekR22 napisał(a):

Dla mnie tak klasa nic nie robi. Ja bym ja bym ją skasował bez mrugnięcia okiem.

Dlaczego?
dodaje kontenery, bo sprawdzałem?

Tak dodaje kontenery, ale robi to w taki sposób, żeby utrudnić czytanie kodu i jego rozumienie.
Ta klasa magicznie zmienia wartości, które kiedyś w przeszłości zostały jej przekazane.
Ktoś kto potem będzie czytał ten, kod będzie szukał czemu mu się te zmienne zmieniają i będzie miał kłopot ze zrozumieniem, że to się dzieje w zupełnie innym miejscu.
To jest najgorszy przypadek nieoczekiwanego side effect.

Na dodatek, o wile prościej i czytelniej mieć po prostu funkcje:

template <typename T, typename L>
void prepend(T& dst, const L& src)
{
     dst.insert(insert.begin(), src.begin(), src.end());
}

template <typename T, typename L>
void append(T& dst, const L& src)
{
     dst.insert(insert.end(), src.begin(), src.end());
}

Podczas użycia widać co się dzieje i będzie to w miarę oczywiste.

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