C++:ssa jäsenmuuttuja käsittääkseni esitellään ja alustetaan näin:
#ifndef PSETTER_H_INCLUDED #define PSETTER_H_INCLUDED #define KOKO 5 class Luokka { static const int taulukko[KOKO][KOKO]; }; const int Luokka::taulukko[KOKO][KOKO] = {{0, 1, 2, 1, 0}, { 1, 3, 5, 3, 1}, { 2, 5, 9, 5, 2}, { 1, 3, 5, 3, 1}, { 0, 1, 2, 1, 0}}; #endif // PSETTER_H_INCLUDED
Ensimmäisen luokan kanssa tuo toimi mutta toisen tekemäni luokan kanssa tuli virheilmoitus "Useita Luokka::taulukko määrittelyitä". Virheilmoitukset osoittaa minne sattuu. PSETTER_H_INCLUDED on yksilöllinen nimi.
Näyttäisitkö mitä oikein teit. Epäilen, että se voisi johtua taulukon staattisuudesta.
Luokka toimii kyllä kun otan toisesta projektiini kuuluvasta .cpp -tiedostosta pois includen tähän .h -tiedostoon:
/* luokka2.cpp */ //Tämä pois niin yllä oleva luokka toimii #include "luokka.h"
Taulukon määrittely ei kuulu otsikkoon vaan cpp-tiedostoon (tässä ilmeisesti psetter.cpp). Muuten se sisällytetään ohjelmaan kerran jokaista cpp-tiedostoa kohti, mistä virheilmoituskin johtuu.
Siirsin alustuksen tuollaisenaan .cpp-tiedostoon ja alkoi toimia. Se onkin tietenkin paljon loogisempaa.
Hauskaa ettei tuo #ifndef - #endif suojaa taulukon alustamista (eli määrittelyä?), vaan pelkästään kuvailemista. Otsikkotiedostot siis ajetaan kahdella eri tavalla kääntäjässä. Ohjelmoijan pitää itse osata laittaa koodit oikeaan tiedostoon...
jsbasic kirjoitti:
Otsikkotiedostot siis ajetaan kahdella eri tavalla kääntäjässä.
Ei suinkaan, kaikki koodi käännetään tasan yhdellä tavalla. Kannattaa lukea oppaat C:n esikääntäjästä ja C++:n esittelyistä ja määrittelyistä sekä koodivinkit koodin jakamisesta tiedostoihin C-tyylisen ja C++-tyylisen koodin tapauksissa. Jos näiden jälkeen vielä on epäselvyyttä siitä, miksi yhdellä tavalla toimii ja toisella ei, kysy toki. :)
Taulukoihin ja olioihin liittyen olisi vielä tyhmä kysymys:
Kun olion konstruktori tai metodi ottaa vastaan taulukon näin...
//triviaali esimerkki void setTaulukko(char taulukko[]) { ... }
...niin miten olion jäsenmuuttujaan voi tallentaa viittauksen syötettävästä taulukosta jotta olio voisi jatkossa käsitellä taulukkoa.
PS. Omassa erikoistapauksessa taulukko on muotoa const ja taulukon lukeminen pitäisi olla nopeaa.
Voit tallentaa viittauksen pointteriin näin
class A { private: int *t; public: void set(int t1[]) { t = t1; } };
Mutta entäs 2-ulotteinen taulukko?
Näin saa tehtyä osoittimen 2-ulotteiseen taulukkoon mutta sitä voi käsitellä vain 1-ulotteisena.
int taulukko[][]={{1,2,3},{4,5,6},{7,8,9}}; int *osoitin; osoitin = *taulukko; int kolmasAlkio = *(osoitin+2);
No, taulukkoa on nopeampi käsitellä 1-ulotteisena. Kaksiulotteiseen taulukkoon osoittaminen vaatii kuitenkin jossain sen kertolaskun, eikö niin?
Tuollaisten nopeuserojen miettiminen on ennenaikaista optimointia, joka on tunnetusti kaiken pahan alku ja juuri. Lisäksi laskutoimitusten määrä ja laatu eivät määrää suoraan ohjelman suoritusnopeutta.
Kaksiulotteiseen C-taulukkoon voit kuitenkin viitata tuplapointterilla.
int t[][] = {{1,2},{3,4}}; int **p = t;
Kannattaa muistaa, että kaksiulotteisen taulukon käsittely yksiulotteisena onnistuu vain tietyissä tapauksissa.
Aihe on jo aika vanha, joten et voi enää vastata siihen.