Форум программистов, компьютерный форум CyberForum.ru

классы. ошибка при вызове конструктора с параметрами - C++

Восстановить пароль Регистрация
 
Levenyatko
2 / 2 / 0
Регистрация: 05.07.2012
Сообщений: 99
26.11.2012, 03:57     классы. ошибка при вызове конструктора с параметрами #1
подскажите, почему при вызове конструктора с параметрами выдает ошибку сегментации

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include <iostream>
 
using namespace std;
 
class Country
{
private:
    char *Name_Country;
    float Naselenije;
    char *Forma_Pravl;
public:
    Country();
    virtual ~Country();
    
    char *GetName_Country();
    float GetNaselenije();
    char *GetForma_Pravl();
        
    void SetName_Country(char *newVal);
    void SetNaselenije(float newVal);
    void SetForma_Pravl(char *newVal);
    
    virtual float GetPloshad()=0; 
    virtual void SetPloshad(float newVal)=0;
    virtual float GetOnePloshad(int i)=0;
};
 
Country::Country()
{
Name_Country=new char[30];
Forma_Pravl=new char[30];
 
Naselenije = 0;
}
                  
Country::~Country()
{
 if(Name_Country != NULL)
delete []Name_Country;
 
    if(Forma_Pravl != NULL)
delete []Forma_Pravl;
}
 
char*Country::GetName_Country()
{   return Name_Country ;       }
 
float Country::GetNaselenije()
{   return Naselenije;     }
 
char* Country::GetForma_Pravl()
{   return Forma_Pravl;   }
 
void Country::SetName_Country(char *newVal)
{       strcpy(Name_Country,newVal);         }
 
void Country::SetNaselenije(float newVal)
{   Naselenije = newVal;          }
 
void Country::SetForma_Pravl(char *newVal)
{   strcpy(Forma_Pravl,newVal);     }
//______________________________________________________________________________
 
class Coutnry_without_islands:public Country
{
private:
        float Ploshad;
public:
       Coutnry_without_islands(){float p=523; Ploshad=p;};
       ~Coutnry_without_islands(){printf("destroy\n");};
        
       float GetPloshad(){ return Ploshad; }; 
       void SetPloshad(float newVal){ Ploshad=newVal; };
       float GetOnePloshad(int i){ return Ploshad; }; 
};
 
class Coutnry_with_islands:public Country
{
private:
    float *Ploshad;
public:
       Coutnry_with_islands(){
                              float p=645; int n=5;
                              Ploshad=new float[5];
                              for(int i=0;i<n;i++)
                              {
                               *(Ploshad+i)=p;
                               p+=30;
                              }
                             };
       ~Coutnry_with_islands(){ printf("destroy\n"); };
 
       float GetPloshad(){
                          float SumPloshad=0;
                          for(int i=0;i<5;i++)
                          {SumPloshad+=Ploshad[i];}
                          return SumPloshad;
                          }; 
       float GetOnePloshad(int i){ return Ploshad[i]; }; 
       void SetPloshad(float newVal)
       { 
            float SumPloshad=0;
            for(int i=0;i<5;i++)
            {SumPloshad+=Ploshad[i];}
            
            Ploshad[0]+=(newVal- SumPloshad);
       };
};
 
//______________________________________________________________________________
 
class Continent
{
private:
    char *Name_Continent;
 
    Country *A;
    Country *B;
 
    int kol1;
    int kol2;
public:
    Continent(); 
    Continent(int N);
    ~Continent();
    
    char *GetName_Continent ();
    void SetName_Continent (char *newVal);
    
    Country &GetCountry (int i, int c){if(c==1){return A[i];}else{return B[i];}};
    void SetCountry(char *name,float nas,float plosh,char* form,int i,int c);
 
    int Getkol(int c){if(c==1){return kol1;}else{return kol2;}};
    void Setkol(int c){if(c==1){kol1++;}else{kol2++;}};
    /*void DelCountry(int i);
    void CreateCountry(int kol);*/
    void Print_Cont();
};
 
void Continent::SetCountry(char *name,float nas,float plosh,char* form,int i,int c)
{
if(c==1){
         A[i].SetName_Country(name);
         A[i].SetNaselenije(nas);
         A[i].SetPloshad(plosh);
         A[i].SetForma_Pravl(form);
        }
else{
         B[i].SetName_Country(name);
         B[i].SetNaselenije(nas);
         B[i].SetPloshad(plosh);
         B[i].SetForma_Pravl(form);
    }
}
 
Continent::Continent()
{
  A = new Coutnry_without_islands[6];
  B = new Coutnry_with_islands[6];
 
  Name_Continent=new char[20];
  kol1=0;
  kol2=0;
}
 
Continent::Continent(int N)
{
  this->Name_Continent=new char[30];
 
  if(N==1){
           strcpy(Name_Continent,"Cont_1");
           kol1=0;
           kol2=0;
 
           SetCountry("Country_without_1.1",223,141,"form_1.1",kol1,1);  Setkol(1);
           SetCountry("Country_without_1.2",423,221,"form_1.2",kol1,1);  Setkol(1);
           SetCountry("Country_without_1.3",704,341,"form_1.3",kol1,1);  Setkol(1);
           SetCountry("Country_without_1.4",523,251,"form_1.4",kol1,1);  Setkol(1);  
           SetCountry("Country_without_1.5",393,171,"form_1.5",kol1,1);  Setkol(1);  
 
           SetCountry("Country_with_1.1",223,241,"form_1.1",kol2,2);  Setkol(2);
           SetCountry("Country_with1.2",363,221,"form_1.2",kol2,2);  Setkol(2);
           SetCountry("Country_with_1.3",224,121,"form_1.3",kol2,2);  Setkol(2);
           SetCountry("Country_with_1.4",123,71,"form_1.4",kol2,2);   Setkol(2);  
          }
  else{
       if(N==2){
           strcpy(Name_Continent,"Cont_2");
           kol1=0;
           kol2=0;
 
           SetCountry("name_Country_without_islands_2.1",283,141,"form_1.1",kol1,1);  Setkol(1);
           SetCountry("name_Country_without_islands_2.2",523,422,"form_1.2",kol1,1); Setkol(1);
           SetCountry("name_Country_without_islands_2.3",304,241,"form_1.3",kol1,1);  Setkol(1);
 
           SetCountry("name_Country_with_islands_1.1",353,241,"form_1.1",kol2,2);  Setkol(2);
           SetCountry("name_Country_with_islands_2.2",293,121,"form_1.2",kol2,2); Setkol(2);
           SetCountry("name_Country_with_islands_2.3",554,221,"form_1.3",kol2,2);  Setkol(2);
           SetCountry("name_Country_with_islands_2.4",723,341,"form_1.4",kol2,2);  Setkol(2);  
          }
       else {printf("Continent ne najden\n");system("pause"); exit(0);}
      }
}
 
Continent::~Continent()
{
 delete[]Name_Continent;
 
 delete[] A;
 delete[] B;
 
 kol1--;
 kol2--;
}
 
char *Continent::GetName_Continent ()
{  return Name_Continent;  }
 
void Continent::SetName_Continent (char *newVal)
{
 strcpy(Name_Continent,newVal);    
}
/*
Country &Continent::GetListCountries (int i)
{
  return ListCountries[i];
}
*/
void Continent::Print_Cont()
{
  printf("___________________________________________________________\n");
  printf("%35s\n",Name_Continent);
  printf("___________________________________________________________\n");
  printf("  Name_Country | Naselenije |  Ploshad  | Form_Pravlenija\n");
  printf("___________________________________________________________\n");
  int i;
  for(i=0;i<kol1;i++)
  {
    printf("%14s | %10.2f | %9.2f | %s\n",A[i].GetName_Country(),A[i].GetNaselenije(),A[i].GetPloshad(),A[i].GetForma_Pravl());
  }
 
  for(i=0;i<kol2;i++)
  {
    printf("%14s | %10.2f | %9.2f | %s\n",B[i].GetName_Country(),B[i].GetNaselenije(),B[i].GetPloshad(),B[i].GetForma_Pravl());
  }
 }  
 
/*
void Continent::DelCountry(int i)
{
    int j,k;
 
        for(; i <kol-1; i++ )
            {
                
                ListCountries[i].SetName_Country(ListCountries[i+1].GetName_Country());
                ListCountries[i].SetNaselenije(ListCountries[i+1].GetNaselenije());
                ListCountries[i].SetPloshad(ListCountries[i+1].GetPloshad());
                ListCountries[i].SetForma_Pravl(ListCountries[i+1].GetForma_Pravl());
            }
     kol--;
}
 
 void Continent::CreateCountry(int kol)
{
      int fl=0;
     char *Name, *Form;
     float pl,n;
 
     Name=new char[30];
     Form=new char[30];
 
     printf("Vvedite name country\n");
     scanf("%s",Name);
 
     printf("Vvedite nasel\n");
     scanf("%f",&n);
     
     printf("Vvedite ploshad\n");
     scanf("%f",&pl);
     
     printf("Vvedite formu\n");
     scanf("%s",Form);   
    SetCountry(Name,n,pl,Form,kol);
}*/
//______________________________________________________________________________
 
int main()
{
    {
     Continent *A=new Continent(1);
 
    //Coutnry_with_islands *A=new Coutnry_with_islands[2];
 /*
    char*Name,*Form;
    float n,pl;
 
     Name=new char[30];
     Form=new char[30];
 
     printf("Vvedite name country\n");
     scanf("%s",Name);
 
 
    printf("Vvedite nasel\n");
     scanf("%f",&n);
     
     printf("Vvedite ploshad\n");
     scanf("%f",&pl);
     
     printf("Vvedite formu\n");
     scanf("%s",Form);   
     A->SetCountry(Name,n,pl,Form,0,1);
     */
     printf("%s\n%f\n%f\n%s\n",A->GetCountry(0,1).GetName_Country(),A->GetCountry(0,1).GetNaselenije(),A->GetCountry(0,1).GetPloshad(),A->GetCountry(0,1).GetForma_Pravl());
 
    // A->Print_Cont();
    }
    system("pause");
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.11.2012, 03:57     классы. ошибка при вызове конструктора с параметрами
Посмотрите здесь:

Ошибка при использовании конструктора C++
при вызове конструктора присваивания надо возвращать ссыль на объект или сам объект. Смысл? Значения нужных полей меняютмся и без этого! C++
Вызов конструктора с несколькими параметрами при использовании push_back() в vector'е C++
C++ Уничтожения информации в объекте класса при повторном вызове конструктора
При вызове конструктора ошибка: L "Buffer is too small" & & 0 C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.11.2012, 04:05     классы. ошибка при вызове конструктора с параметрами #2
Всё не смотрел, но сразу замечу. Именно для того, чтоб избавиться от if(c==1) if(c==2) ... и были придуманы наследование и полиморфизм.
Цитата Сообщение от Levenyatko Посмотреть сообщение
C++
1
2
Country *A;
Country *B;
Цитата Сообщение от Levenyatko Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Continent::SetCountry(char *name,float nas,float plosh,char* form,int i,int c)
{
if(c==1){
              A[i].SetName_Country(name);
              A[i].SetNaselenije(nas);
              A[i].SetPloshad(plosh);
              A[i].SetForma_Pravl(form);
            }
else{
              B[i].SetName_Country(name);
              B[i].SetNaselenije(nas);
              B[i].SetPloshad(plosh);
              B[i].SetForma_Pravl(form);
    }
}
Levenyatko
2 / 2 / 0
Регистрация: 05.07.2012
Сообщений: 99
26.11.2012, 04:29  [ТС]     классы. ошибка при вызове конструктора с параметрами #3
Kuzia domovenok, вот с ними и пытаюсь разобраться..
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.11.2012, 04:52     классы. ошибка при вызове конструктора с параметрами #4
Попробуй лучше
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Continent
{
public:
    Continent();
private:
    char *Name_Continent;
 
    Country **A;
//......
};
Continent::Continent()
{
  A = new Country*[12];
  for (int i=0; i<12; i++)
   if ( страна с номером i имеет острова)
      A[i]=new Coutnry_with_islands();
   else
      A[i]=new Coutnry_without_islands();
 
  Name_Continent=new char[20];
  kol1=0;
  kol2=0;
}
И всё Это будет единственное место в программе где будет if с островами или нет.
У тебя же сейчас в каждом методе класса Continent (например Continent::Print_Cont() )придётся писать два идентичных цикла, обрабатывающих массив А и масссив B. А если у класса Country вдруг появится ещё один-два-десять классов-наследников?

Добавлено через 8 минут
Теперь об ошибках. Смотри, что за непорядок:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Continent::Continent()
{
  A = new Coutnry_without_islands[6];
  B = new Coutnry_with_islands[6];
 
  Name_Continent=new char[20];
  kol1=0;
  kol2=0;
}
 
Continent::Continent(int N)
{
  this->Name_Continent=new char[30];
//....................
Память под A и B выделяется только в случае первого конструктора(без параметров)
Если я захочу создать континент конструктором с параметром N, память не будет выделена.
Забавно, что память под имя континента ты не забыл выделить в обоих случаях, в отличие от A и B!!
Ещё интересно, что в зависимости от случая максимальный размер строки с именем может быть то 20 то 30

Исправь:
C++
1
2
3
4
5
Continent::Continent(int N)
{
  A = new Coutnry_without_islands[6];
  B = new Coutnry_with_islands[6];
  this->Name_Continent=new char[30];
Levenyatko
2 / 2 / 0
Регистрация: 05.07.2012
Сообщений: 99
26.11.2012, 18:02  [ТС]     классы. ошибка при вызове конструктора с параметрами #5
Kuzia domovenok, зачем две звездочки в
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Country **A;

а на это ругается..
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
A = new Country*[12];
* for (int i=0; i<12; i++)
* *if ( страна с номером i имеет острова)
* * * A[i]=new Coutnry_with_islands();
* *else
* * * A[i]=new Coutnry_without_islands();

пыталась еще сделать так:

Country *A[2]={new Country_with_islands[6],new Country_without_islands[4]};
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.11.2012, 18:09     классы. ошибка при вызове конструктора с параметрами #6
Цитата Сообщение от Levenyatko Посмотреть сообщение
а на это ругается..
что конкретно ругает? Надеюсь, ты не копируешь эту кучу звёздочек в начале строк?
Ну? где ответ? жду. Естесственно, то что я написал надо не топорно вставлять, а перерабатывать все обращения к А и В во всей программе.
Levenyatko
2 / 2 / 0
Регистрация: 05.07.2012
Сообщений: 99
26.11.2012, 18:29  [ТС]     классы. ошибка при вызове конструктора с параметрами #7
Kuzia domovenok, звездочки я не копирую..

A = new Country[12];
for (int i=0; i<12; i++)
{ if ( i<6)
A[i]=new Coutnry_without_islands;
else
A[i]=new Coutnry_with_islands;
}

на строчку A = new Country*[12]; пишет

cannot allocate an object of type 'Country', because the folloving function are abstract

Добавлено через 2 минуты
...обращения я переделала..оно же так ничего не обработает..но именно с созданием у меня проблемы..
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.11.2012, 18:30     классы. ошибка при вызове конструктора с параметрами #8
Цитата Сообщение от Levenyatko Посмотреть сообщение
A = new Country[12];
это пишешь ты

A = new Country*[12];
это сказал я.
Разницы не видишь? Зачем изучать ООП, если в чистом Си плаваешь?
Levenyatko
2 / 2 / 0
Регистрация: 05.07.2012
Сообщений: 99
26.11.2012, 18:48  [ТС]     классы. ошибка при вызове конструктора с параметрами #9
я убрала две звездочки

Country **A;

потому что не понимаю зачем они.. я просто написала Country *A;

Добавлено через 14 минут
Kuzia domovenok,
Цитата Сообщение от Levenyatko Посмотреть сообщение
зачем две звездочки
??
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2012, 22:09     классы. ошибка при вызове конструктора с параметрами
Еще ссылки по теме:

C++ Пояснение к аргументам при вызове функции, и запрет конструктора по умолчанию
Ошибка при вызове метода класса, при чтении из файла C++
Что за ошибка при вызове конструктора? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
26.11.2012, 22:09     классы. ошибка при вызове конструктора с параметрами #10
ОК, давай сначала.
Ты знаешь как пользоваться указателями?
Я предположил, что знаешь, судя по тому, что память под динамический массив выделять умеешь.
Напомню, указатель А на любой тип Т объявляется как

Т* А;

Оператор new возвращает нам указатель на первый элемент выделенного массива. вот как мы его используем.
то есть, чтобы иметь массив из элементов типа Т, нужно иметь указатель на Т и выделить память как

Т* A=new T[12]; (формула 1)

Это ясно. В твоём примере T это Country, т.е. сам объект, т.е. в массиве будет последовательно идти несколько больших кусков памяти, содержащих Name_Country;Naselenije и Forma_Pravl; и идущих друг за другом.
И что важно!(и является причиной отказа от твоего способа) Эти хранимые нами объекты будут созданы именно в этот момент! То есть для каждого объекта будет вызван конструктор. Но ведь мы ещё не решили какие из них с континентами, а какие нет. Более того: даже если б мы решили это, С++ нам просто не позволит хранить объекты разных типов в массиве. Ведь неспроста массивы имеют тип. В массиве нельзя хранить объекты разного размера и вообще... Класс Country абстрактный и даже еслиб захотели создать одного типа, мы б не создали массив объектов класса Country.

Я же выделяю массив не из 12 элементов, а из 12 указателей. Что это даёт? Каждый указатель имеет одинаковый размер, при создании массива указателей не создаётся никаких объектов, на которые они указывают: указатели неинициализированы, никаких конструкторов не вызывается. Это просто ячейки для хранения адресов в памяти, в которых пока случайный мусор. У них нет полей Name_Country;Naselenije и Forma_Pravl; Это не объекты это указатели на будущие наши объекты.
Следовательно, конструктор какого объекта будет вызван для каждой из 12 стран мы определяем уже после выделения массива.

Итак, как выделить массив указателей? Подставляем в формулу 1 вместо типа Т тип указателя на страну (Country*) и получаем

Country** A= new Country* [12];

Теперь ясно, откуда 2 звёздочки?

Теперь каждую страну можно создать отдельно друг от друга и в качестве создаваемой страны можно выбрать любого неабстрактного наследника класса Country.

В цикле по i даём команду

A[i]=new Coutnry_without_islands; //или без островов... - в зависимости от i

Это даёт нам возможность в дальнейшем обращаться ко всем странам вне зависимости с островами они или нет. Без всяких if(c==1){
Yandex
Объявления
26.11.2012, 22:09     классы. ошибка при вызове конструктора с параметрами
Ответ Создать тему
Опции темы

Текущее время: 16:18. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru