Перейти к содержанию

C++ конструктор


Antonshka

Рекомендуемые сообщения

Привет всем,

 

кто-нибудь из вас сталкивался с ошибкой компилятора ""error C2082: переопределение формального параметра "pstr"?

скрипт

Спойлер

#include "pch.h" 
#include <iostream>
using namespace std;

class String 
{
protected:
	enum { MAX = 20 };
	char str[MAX];
public:
	String()
	{
		str[0] = '\0';
	}
	String(const char s[]) 
	{
		strcpy_s(str, s);
	}
};

class Pstring : public String
{
public:
	Pstring(const char pstr[])
	{ String(pstr); }
	void show()
	{ cout << str; }
};

int main()
{
	Pstring s1 = "one";
	s1.show();
return 0;
}

 

 

если вместо

Pstring(const char pstr[])
{ String(pstr); }

записать

Pstring(const char pstr[]) : String(pstr)
{ }

то ошибки нет.

 

Решение проблемы взятое из Microsoft Docs -

В теле функции переопределен формальный параметр функции. Чтобы устранить эту ошибку, удалите повторное определение.

void func(int i) {
   int i;   // C2082
   int ii;   // OK
}

Никак не могу найти причину. Ведь я вызываю конструктор с одним параметром класса String, и передаю ему аргумент pstr.

Как правильно вызвать конструктор String, из тела конструктора Pstring, передав ему при этом параметр pstr?

 

Изменено пользователем Antonshka
Ссылка на комментарий
Поделиться на другие сайты

Выбирай, что больше нравится. Ничего нового тут нет, все что сказано выше.

 

1.

Спойлер

class Pstring :  String
{
public:
	Pstring(const char pstr[]) : String(pstr) {};
	void show() const { cout << String::str; };
};

 

 

2.

Спойлер

class Pstring : String
{
public:
	Pstring(const char pstr[]) : pstr_(pstr) {};
	void show() const { cout << pstr_; };

	const char* pstr_;
};

 

 

Мне нравится как выглядит второй вариант?

Ссылка на комментарий
Поделиться на другие сайты

В конце книги Лафоре есть ответы на некоторые его задачи. Есть ответ и на эту задачу.

Вот (нерабочий) ответ, из оригинала книги

Спойлер

// ex9_2.cpp
//inheritance from String class
#include <iostream>
#include <cstring> //for strcpy(), etc.
using namespace std;
////////////////////////////////////////////////////////////////
class String //base class
{
protected: //Note: can’t be private
	enum { SZ = 80 }; //size of all String objects
	char str[SZ]; //holds a C-string
public:
	String() //constructor 0, no args
	{
		str[0] = ‘\0’;
	}
	String(char s[]) //constructor 1, one arg
	{
		strcpy(str, s);
	} // convert string to String
	void display() const //display the String
	{
		cout << str;
	}
	operator char*() //conversion function
	{
		return str;
	} //convert String to C-string
};
////////////////////////////////////////////////////////////////
class Pstring : public String //derived class
{
public:
	Pstring(char s[]); //constructor
};
//--------------------------------------------------------------
Pstring::Pstring(char s[]) //constructor for Pstring
{
	if (strlen(s) > SZ - 1) //if too long,
	{
		for (int j = 0; j < SZ - 1; j++) //copy the first SZ-1
			str[j] = s[j]; //characters “by hand”
		str[j] = ‘\0’; //add the null character
	}
	else //not too long,
		String(s); //so construct normally
}
////////////////////////////////////////////////////////////////
int main()
{ //define String
	Pstring s1 = “This is a very long string which is probably “
		“no, certainly--going to exceed the limit set by SZ.”;
	cout << “\ns1 = ”; s1.display(); //display String
	Pstring s2 = “This is a short string.”; //define String
	cout << “\ns2 = ”; s2.display(); //display String
	cout << endl;
	return 0;
}

 

 

Непонятно почему в этом скрипте вызывается конструктор базового класса из тела конструктора производного класса.

 

@JustHack

Понятно, но в списке инициализации нельзя выполнить какое-либо условие (а оно должно быть в этой задаче), потому видимо вызов конструктора базового класса и был перенесен в тело конструктора.

 

В интернете нашел еще такое решение,

вместо вызова конструктора

else //not too long,	
		String(s);

использовать уже непосредственно саму функцию того конструктора

else //not too long,	
		strcpy_s(str, s);

 

Изменено пользователем Antonshka
Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Antonshka сказал:

Непонятно почему в этом скрипте вызывается конструктор базового класса из тела конструктора производного класса.

 

Возможно использовалась старая спецификация языка, которая позволяла это делать. Это надо смотреть по какой версии писалась книга.

Хотя код достаточно странный из примера и некоторые куски кода вообще не понятно как должны работать.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.