SPiNMedlem sedan mars 20007 896 inlägg Nu tänkte jag bättre på mina C++-kunskaper, så räkna med att svara på en hel del frågor, gurus. ;)
Klasser är väl där jag "slutade" sist, och nu har jag lite problem. I en include-fil har jag följande:
#include <string>
using namespace std;
class CBike {
public:
CBike ();
~CBike ();
int GetSeats ();
protected:
int seats;
};
class CBmx : CBike {
};
class CTandem : CBike {
public:
CTandem ();
};
CBike::CBike () {
seats = 1;
}
int CBike::GetSeats () {
return seats;
}
CTandem::CTandem () {
seats = 2;
}
Mitt dokument med main-metoden:
#include <iostream>
using namespace std;
#include "MIN_INCLUDE.h"
void main () {
CBmx * bmx = new CBmx ();
cout << "BMX, antal platser: " << bmx->GetSeats () << endl;
delete bmx;
CTandem * tandem = new CTandem ();
cout << "Tandem, antal platser: " << tandem->GetSeats () << endl;
delete tandem;
}
Får felmeddelandet:
'int GetSeats ()' is inaccessible
whitin this context
Pekare mot cout-raderna.
SweyMedlem sedan apr. 20003 971 inlägg För att CTandem ska ärva rättigheterna från CBike måste public användas på detta sätt:
class CTandem : public CBike {};
Annars görs en privat ärvning, vilket innebär att alla publika och skyddade medlemmar endast kan användas inom klassen och inte utanför.
Det finns ingen anledning att ha ett C framför Tandem och Bike. Det är dålig design och ska undvikas.
class Tandem : public Bike {};
SPiNMedlem sedan mars 20007 896 inlägg Okey, tack för svaret! :)
Kan jag då också deklarera integern seats som private, eller gäller fortfarande protected?
Orsaken till att jag har C framför klasserna är att jag vill skilja mina struct:ar från mina class:er.
PeWMedlem sedan juni 200010 432 inlägg Du behöver inte deklarera <string> i din header och du ska absolut undvika att använda using namspace i headerfiler. Om du måste använda standardklasser och namnrymder är det bättre att isf skriva: std::string när du använder / deklarerar något därav.
Du behöver inte deklarera destruktorn om du inte gör nåt med den.
Sen kan det vara trevligare att använda initieringslista ist för att bygga på blocket i konstruktorn:
CBike::CBike ():seats(1) { }
CTandem::CTandem ():seats(2) { }
Din kod ett typexempel på hur man skulle kunna använda abstrakta klasser (i detta fall skulle Bike kunna vara det) som du isf skapar med virtual. Då är det lika dynamiskt (och smidigt) som i JAVA att skyffla data med respektive klassers metoder. :)
SPiNMedlem sedan mars 20007 896 inlägg Koden jag skrev var inte hela som jag använder, jag glömde kvar inkluderingen bara och jag har lite skoj i destruktorn... :)
Din kod ett typexempel på hur man skulle kunna använda abstrakta klasser (i detta fall skulle Bike kunna vara det) som du isf skapar med virtual. Då är det lika dynamiskt (och smidigt) som i JAVA att skyffla data med respektive klassers metoder.
Jäpp, det har du helt riktigt i. Det tänkte jag aldrig på. :)
Varför ska man undvika using namespace i header-filer?
Kan jag deklarera seats som private och ändå kunna hämta från en underklass om jag deklarerar den som public i "ärvningen", som Swey visade? Eller gäller protected? Troligtvis är det väl som i Java, att private endast funkar i den egna klassen, protected fungerar även i subklasser?
UlfTMedlem sedan maj 20018 027 inlägg
Varför ska man undvika using namespace i header-filer?
I ditt fall med "using namespace std" i "min_include.h", kommer inkluderandet av den headerfilen innebära att du applicerar det namespacet på allt som kommer efter "include" i c-filen. I just ditt fall blir det inget problem eftersom du i alla fall hade tänkt använda det namespacet. Men rent allmänt är det ju bra om man på ett enkelt sätt alltid kan se vilket namespace som gäller utan att behöva rota i headerfilerna som man har inkluderat.
SweyMedlem sedan apr. 20003 971 inlägg
Kan jag deklarera seats som private och ändå kunna hämta från en underklass om jag deklarerar den som public i "ärvningen", som Swey visade?
Nej, i regel kan du endast sänka behörigheten.
Public ärver public-medlemmar som public och protected-medlemmar som protected.
Protected ärver public som protected och protected som protected.
Private (om inget anges) ärver public som private och protected som private.
Medlemmar deklarerade som private är alltid oåtkomliga i underklasser.
I .NET kan man endast ärva som public. MFC och VCL använder dessutom endast public-ärvning. De andra metoderna används vad jag vet väldigt sällan.
SPiNMedlem sedan mars 20007 896 inlägg Tackar, tackar. :)
Jag har sökte lite angående stack- och heapallokeringar, och hittade en väldigt mycket intressant diskussion: http://www.webforum.nu/showthread.php?s=&threadid=27590&highlight=stack+heap
Vad kom de fram till egentligen? :)
Vad är smartast att använda, följande:
CClass *var = new CClass (); // Heapallokering?
Eller:
CClass var;
CClass *pVar = &var; // Stackallokering?
UlfTMedlem sedan maj 20018 027 inlägg
Jag har sökte lite angående stack- och heapallokeringar, och hittade en väldigt mycket intressant diskussion: http://www.webforum.nu/showthread.p...ight=stack+heap
Vad kom de fram till egentligen?
Att stackallokering är mycket snabbare än heapallokering. Man bör väl tillägga att det kan finnas andra omständigheter som kan motivera heapallokering i en del fall. Så därför går det inte att utan vidare säga vad som är smartast i just ditt fall.
SPiNMedlem sedan mars 20007 896 inlägg Vilka är dessa omständigheter, finns det några konkreta? Jag har själv inget fall, utan är mest nyfiken. :)
Jag tog mig också friheten att radera ditt svar på ditt eget inlägg. ;)
UlfTMedlem sedan maj 20018 027 inlägg
Jag tog mig också friheten att radera ditt svar på ditt eget inlägg.
Bra. Jag blev lite förvånad över en del saker som hände när jag råkade klicka lite fel. ;)
Heap-allokering kan vara bra om du behöver en mer dynamisk minnesallokering. Ett exempel är om du har en länkad lista. Då behöver inte programmet veta i förväg hur mycket som ska allokeras. Programmet kan under körningens gång allokera element efter element i den länkade listan.
SPiNMedlem sedan mars 20007 896 inlägg
...när jag råkade klicka lite fel.
Lite fel? Du måste ja klickat fel minst två gånger. ;) §e
Tack för svaret ivf, det skulle jag ju hur lätt som helst kunnat gissa mig till om jag hade tänkt lite! :bire
PeW pratade lite om abstrakta klasser, och jag undrar nu hur jag skapar dem... Det enda vettiga jag har hittat är att man använder nyckelordet virtual på en del metoder ( Alla metoder? ) - stämmer det? :)
UlfTMedlem sedan maj 20018 027 inlägg Nyckelordet "virtual" kommer väl till pass för abstrakta klasser. Du deklarerar en metod som:
virtual int GetSeats() = 0;
Observera "= 0" på slutet. Det räcker med att en av metoderna är deklarerad så, så är klassen abstrakt. Be mig inte förklara logiken bakom detta ;) Själv hade jag föredragit att man hade haft ett nyckelord typ "abstract" för att deklarera klassen. Nåja, man kan ju inte alltid få som man vill ;)
SPiNMedlem sedan mars 20007 896 inlägg Om jag ber dig förklara varför man sätter "=0", efter då? :)
Själv hade jag föredragit att man hade haft ett nyckelord typ "abstract" för att deklarera klassen. Nåja, man kan ju inte alltid få som man vill
*host* Java *host* ;)
PhorpherMedlem sedan feb. 20002 300 inlägg virtual void gurka() = 0;
Betyder att funktionen är "pure virtual". Dvs. den har ingen implementering i den klass den tillhör och du kan således inte instansiera klassen just för att den blir abstrakt.
Det är upp till underklasserna att implementera gurka.
Kan jämföras med javas interface.