Uniknięcie wywołania konstruktora klasy bazowej

0

Witam,

czy ktos moze mi powiedziec, czy mozna uniknac wywolania domyslnego konstruktora klasy bazowej w kodzie jaki jest poniżej:

class A{
  A(void){ }
}

class B : public A {
  B(void){ }
}

B objB = new objB();

oczywiście jestem w stanie sprawić aby wywoływał sie dowolny konstruktor klasy bazowej poprzez liste inicjalizacyjną, ale czy można zmodyfikowac kod ktory podalem tak aby przy tworzeniu obiektu klasy B nie wywolywal się konstruktor klasy A ?

pzdr
squash

0

To zależny co chcesz dokładnie osiągnąć:
np możesz

class A{
  A(void){ }
  A(Downlny_typ_zmiennej zmienna) { }
}
 
class B : public A {
  B(void) : A(jakas_zmienna){ }
}
 
B objB = new objB();

I teraz unikniesz wywołania A(void){ }

0

Dzieki za odpowiedz,

napisalem jednak ponizej mojego kodu ze wiem, ze moge wykorzystac liste inicjalizacyjna i tak tez wczesniej zrobilem zanim napisalem ten post.

Jestem ciekawy jednak, czy mozna ktos zna sposob jak mozna to inczej obejsc?

pzdr
squash

0

Po co chcesz to omijać? Jest to może rzeczywistym problemem w wydajności? Ogólnie jeżeli dobrze rozumiem klasy w C++ to klasa pochodna zawiera całą klasę nadrzędną i się tak zachowuję. Tym samym klasa bazowa musi zostać skonstruowana. Tak po prostu działa polimorfizm w C++ (nie wiem jeszcze dokładnie jak to wygląda w innych językach, ale z niskopoziomowym podejściem C++ chyba nic więcej nie wskórasz, niż odpowiednia lista inicjalizacyjna). Powiedz dlaczego nie chcesz wywoływać konstruktora klasy bazowej, to może mimo swojej ograniczonej wiedzy uda mi się ci pomóc.

0

Tak jak juz wczesniej napisalem, trywialnie dalem sobie z tym rade stosując listę inicjalizycjna w konstruktorze klasy potomnej.
Zadając to pytanie chcialem z pierwszej reki od znawcow tematu dowiedziec sie, czy mozna bylo to zrobic inaczej.
Jesli chodzi o to czemu to jest to potrzebne - po prostu konstruktor domyslny klasy bazowej podejmuje dzialania, których nie chcę aby podejmował jesli tworzę obiekt klasy potomnej.

pozdrawiam
squash

0

Trudno powiedzieć... Robię systemik, w którym główna aplikacja jest napisana w C# natomiast krytyczne wydajnościowo obliczenia wykonywane są w C++ native, a pośrednikiem między tymi dwiema warstwami jest kod C++ managed. I to właśnie jedna z klas w managed wymusiła zastosowanie takiego rozwiązania. Nie jestem specem w teorii ale przeczuwam, że przy takich kombinacjach teoretyczne modele nie zawsze mają zastosowanie.

0

Łoj, no rzeczywiście, to może doprowadzać do problemów. Z jednej strony ładny kod, z drugiej szybki, na szczęście dzięki postępowi w konstrukcji kompilatorów i interpreterów można pisać coraz ładniejszy kod który będzie działał szybko. Ogólnie to bym w takim wypadku zrezygnował z polimorfizmu na rzecz bardziej czytelnych rozwiązań, choć to zależy od szczególnego przypadku (programowanie obiektowo zorientowane jest wg mnie najlepszym wynalazkiem informatycznym od czasu procedur).

0
Squash napisał(a)

po prostu konstruktor domyslny klasy bazowej podejmuje dzialania, których nie chcę aby podejmował jesli tworzę obiekt klasy potomnej.

Do takiego celu mogę zaproponować poniższe rozwiązanie, ale niestety podałeś za mało informacji, aby można było ocenić, jakie rozwiązanie będzie najlepsze dla tego konkretnego problemu.

class I {                 // przenosisz tu wszystko co masz w A, zostawiajac w A tylko definicje konstruktora
  I(void) { }
};

class A : public I {
  A(void){ }
}
 
class B : public I {
  B(void){ }
}
 
B objB = new objB();
0

Obawiam się, że to niemożliwe żeby wydajnościowo np C# zrównał się z c++ native. Prędzej dojdzie do tego, że moc komputerów spowoduje, że nie będziemy brali pod uwagę tego, że coś się wykonuje 5x szybciej, bo czas przykladowych obliczeń bedzie wynosil albo 0.1 s albo 0.02 :)
Powiem, że dla ciekawości robilem sobie testy szybkości. I jakbym nie liczyl, to przy moich potrzebach obliczen proporcje czasu dzialania kodu C#, c++ managed, c++ native wynosily odpowiednio okolo 6:5:1

@t0m_k
dzieki ale wole liste inicjalizacyjna :) Klas w moim kodzie mam aż nadto :)

pzdr
squash

0

Obawiam się, że to niemożliwe żeby wydajnościowo np C# zrównał się z c++ native
kompilator C# ma dość zaawansowaną optymalizację, więc może się okazać szybszym od kodu w C++ bez optymalizacji.
Średnia powolniejszość C# wynika nie z tego że to maszyna wirtualna, a z tego że ma intensywny runtime-checking którego nie da się wyłączyć.

I jakbym nie liczyl, to przy moich potrzebach obliczen proporcje czasu dzialania kodu C#, c++ managed, c++ native wynosily odpowiednio okolo 6:5:1

Coś musiałeś mocno nie tak robić. Rozumiem różnicę kilku czy kilkudziesięciu procent, ale 5-krotna to raczej nie możliwe — chyba że mówimy o wykorzystywaniu instrukcji SIMD.

0

Nie da się tego zrobić. Gdyby np w klasie A były zdefiniowane pola stałe lub referencje (w szczególności prywatne) to, kto musiałby się nimi zająć? Może to zrobić tylko jakiś konstruktor z klasy A.

0

Qsort jest wolniejszy od std::sort właśnie z powodu tego że musi wywoływać metodę dla każdego porównania.

I jakbym nie liczyl, to przy moich potrzebach obliczen proporcje czasu dzialania kodu C#, c++ managed, c++ native wynosily odpowiednio okolo 6:5:1

Co do wydajności C#, chyba nie używałeś do benchmarków wersji debug? Różnica między szybkością Debug i Release potrafi wynosić w przypadku VS nawet do 50x...
Nie mówię że C# jest szybszy od C++ (ale będzie mam nadzieję ;) bo ma prawo wykonywać optymalizacje które natywnym programom się nie śniły), ale różnica sześciokrotna (poza kilkoma wyjątkami, niemożliwymi do uniknięcia, jak np. interop) jest IMO raczej niemożliwa.

@temat - ostatecznie możesz to zrobić starym, dobrym sposobem:

class A : ... { ... static void init(A *obj) { ... } ... }

A *a_obj = (A*)malloc(sizeof(A));
A::init(a_obj);

Nie testowałem tego, ale sam pomysł, o ile nie zapomniałem o jakimś kruczku, powinien działać.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.