2009-05-14 10 views
32

J'ai lu beaucoup de tutoriels sur la classe C++ mais ils manquent quelque chose que d'autres tutoriels incluent.Comment écrire une classe simple en C++?

Quelqu'un peut-il me montrer comment écrire et utiliser une classe C++ très simple qui utilise la visibilité, les méthodes et un simple constructeur et destructeur?

+30

Ceci _has_ être devoirs! – xian

+7

Je peux difficilement croire que vous n'avez pas trouvé d'exemples via googling sur ce sujet. La plupart des exemples ci-dessous, il suffit de copier collé ici, à partir de tutoriels sur le web. –

+7

vous sérieusement ne doit pas avoir l'air très dur. –

Répondre

8
class A 
{ 
    public: 
    // a simple constructor, anyone can see this 
    A() {} 
    protected: 
    // a simple destructor. This class can only be deleted by objects that are derived from this class 
    // probably also you will be unable to allocate an instance of this on the stack 
    // the destructor is virtual, so this class is OK to be used as a base class 
    virtual ~A() {} 
    private: 
    // a function that cannot be seen by anything outside this class 
    void foo() {} 
}; 
25

bien documenté exemple pris et expliqué mieux de Constructors and Destructors in C++:

#include <iostream>   // for cout and cin 

class Cat      // begin declaration of the class 
{ 
    public:      // begin public section 
    Cat(int initialAge);  // constructor 
    Cat(const Cat& copy_from); //copy constructor 
    Cat& operator=(const Cat& copy_from); //copy assignment 
    ~Cat();     // destructor 

    int GetAge() const;  // accessor function 
    void SetAge(int age);  // accessor function 
    void Meow(); 
private:      // begin private section 
    int itsAge;    // member variable 
    char * string; 
}; 

// constructor of Cat, 
Cat::Cat(int initialAge) 
{ 
    itsAge = initialAge; 
    string = new char[10](); 
} 

//copy constructor for making a new copy of a Cat 
Cat::Cat(const Cat& copy_from) { 
    itsAge = copy_from.itsAge; 
    string = new char[10](); 
    std::copy(copy_from.string+0, copy_from.string+10, string); 
} 

//copy assignment for assigning a value from one Cat to another 
Cat& Cat::operator=(const Cat& copy_from) { 
    itsAge = copy_from.itsAge; 
    std::copy(copy_from.string+0, copy_from.string+10, string); 
} 

// destructor, just an example 
Cat::~Cat() 
{ 
    delete[] string; 
} 

// GetAge, Public accessor function 
// returns value of itsAge member 
int Cat::GetAge() const 
{ 
    return itsAge; 
} 

// Definition of SetAge, public 
// accessor function 
void Cat::SetAge(int age) 
{ 
    // set member variable its age to 
    // value passed in by parameter age 
    itsAge = age; 
} 

// definition of Meow method 
// returns: void 
// parameters: None 
// action: Prints "meow" to screen 
void Cat::Meow() 
{ 
    cout << "Meow.\n"; 
} 

// create a cat, set its age, have it 
// meow, tell us its age, then meow again. 
int main() 
{ 
    int Age; 
    cout<<"How old is Frisky? "; 
    cin>>Age; 
    Cat Frisky(Age); 
    Frisky.Meow(); 
    cout << "Frisky is a cat who is " ; 
    cout << Frisky.GetAge() << " years old.\n"; 
    Frisky.Meow(); 
    Age++; 
    Frisky.SetAge(Age); 
    cout << "Now Frisky is " ; 
    cout << Frisky.GetAge() << " years old.\n"; 
    return 0; 
} 
+2

Hate get/set ici. Permet l'abus de chat. Vous ne devriez pas être en mesure de définir l'âge (car il peut être plus jeune), mais vous devriez être capable d'incrémenter l'âge. –

+2

Ou plutôt, il devrait y avoir SetBirthday(), puis GetAge(). – Reunanen

+3

De même, comme cela est destiné à un échantillon d'apprentissage, les accesseurs doivent être marqués comme constants, comme miaulement car ils ne modifient pas le contenu de l'objet. –

4
#include <iostream> 
#include <string> 

class Simple { 
public: 
    Simple(const std::string& name); 
    void greet(); 
    ~Simple(); 
private: 
    std::string name; 
}; 

Simple::Simple(const std::string& name): name(name) { 
    std::cout << "hello " << name << "!" << std::endl; 
} 

void Simple::greet() { 
    std::cout << "hi there " << name << "!" << std::endl; 
} 

Simple::~Simple() { 
    std::cout << "goodbye " << name << "!" << std::endl; 
} 

int main() 
{ 
    Simple ton("Joe"); 
    ton.greet(); 
    return 0; 
} 

Silly, mais, vous y êtes. Notez que "visibilité" est un abus de langage: accessibilité de contrôle public et privé, mais même les choses "privées" sont encore "visibles" de l'extérieur, mais pas accessible (c'est une erreur d'essayer et d'y accéder).

+0

En fait, la visibilité peut causer des problèmes. Le compilateur choisit la fonction surchargée à appeler en fonction de la visibilité et de la meilleure correspondance dans les arguments, et peut se retrouver avec une fonction inaccessible. Ces concepts peuvent devenir confus. –

+0

Pourquoi Alex a-t-il utilisé string & name au lieu du nom de chaîne – Babiker

+2

"const string & name" signifie qu'aucune copie n'est effectuée, "string name" indique au compilateur de faire une copie. Pourquoi demander une copie quand vous n'en avez pas besoin? C'est une bonne habitude à acquérir, passer des args (qui ne sont pas des types de valeur simples tels que int, pointeur, etc) par const ref lorsque vous les utilisez en lecture seule. –

10

Même s'il est un étudiant, vaut la peine d'essayer de répondre parce qu'il est complexe pas facile au moins pour un nouveau visiteur de C++ :)

Classes en C++ servir une intersection de deux paradigmes de conception,

1) ADT :: ce qui signifie fondamentalement un nouveau type, quelque chose comme des entiers 'int' ou des nombres réels 'double' ou même un nouveau concept comme 'date'. dans ce cas, la classe simple devrait ressembler à ceci,

class NewDataType 
{ 
public: 
// public area. visible to the 'user' of the new data type. 
. 
. 
. 
private: 
// no one can see anything in this area except you. 
. 
. 
. 
}; 

c'est le squelette le plus élémentaire d'un ADT ... Bien sûr, il peut être plus simple en ignorant l'espace public! et en effaçant les modificateurs d'accès (public, privé) et le tout sera privé. mais c'est juste un non-sens. Parce que le NewDataType devient inutile! Imaginez un 'int' que vous pouvez simplement déclarer mais vous ne pouvez rien faire avec.

Ensuite, vous avez besoin de quelques outils utiles qui ne sont pas fondamentalement requis pour l'existence de NewDataType, mais vous les utilisez pour laisser votre type ressembler à n'importe quel type 'primitif' dans la langue.

le premier est le constructeur. Le constructeur est nécessaire dans de nombreux endroits de la langue. regardez int et essayons d'imiter son comportement.

int x; // default constructor. 

int y = 5; // copy constructor from a 'literal' or a 'constant value' in simple wrods. 
int z = y; // copy constructor. from anther variable, with or without the sametype. 
int n(z); // ALMOST EXACTLY THE SAME AS THE ABOVE ONE, it isredundant for 'primitive' types, but really needed for the NewDataType. 

chaque ligne des lignes ci-dessus est une déclaration, la variable est construite là.

et à la fin imaginer les variables int ci-dessus dans une fonction, cette fonction est appelée « fun »,

int fun() 
{ 
    int y = 5; 
    int z = y; 
    int m(z); 

    return (m + z + y) 
    // the magical line. 
} 

vous voyez la ligne magique, ici vous pouvez dire au compilateur tout ce que vous voulez! après avoir tout fait et votre NewDataType n'est plus utile pour la portée locale comme dans la fonction, vous TUEZ. un exemple classique serait de libérer la mémoire réservée par «nouveau»!

donc notre très simple NewDataType devient,

class NewDataType 
{ 
public: 
// public area. visible to the 'user' of the new data type. 
    NewDataType() 
    { 
     myValue = new int; 
     *myValue = 0; 
    } 

    NewDataType(int newValue) 
    { 
     myValue = new int; 
     *myValue = newValue; 
    } 

    NewDataType(const NewDataType& newValue){ 

     myValue = new int; 
     *myValue = newValue.(*myValue); 
    } 
private: 
// no one can see anything in this area except you. 
    int* myValue; 
}; 

Maintenant, ce squelette est le très basique, pour commencer à construire une classe utile, vous devez fournir des fonctions publiques.

Il y a beaucoup de petits outils à considérer dans la construction d'une classe en C++,

. . . .

2) Objet :: ce qui signifie fondamentalement un nouveau type, mais la différence est qu'il appartient aux frères, sœurs, ancêtres et descendants. regardez 'double' et 'int' en C++, le 'int' est un soleil de 'double' parce que chaque 'int' est un 'double' au moins dans le concept :)

Questions connexes