#net #visual_cpp #cpp_cli #clr
Есть 2 программы на C++/CLR:
1)
#include "stdafx.h"
using namespace System;
String^ InsertSpacesBeforBigLetters(String ^str)
{
for (int i = 1; i < str->Length; i++)
{
if (str[i] >= 'A' && str[i] <= 'Z')
{
str = str->Insert(i, " ");
++i;
}
}
return str;
}
int main()
{
Console::WriteLine("Enter string:");
String ^input_str = Console::ReadLine();
//input_str = InsertSpacesBeforBigLetters(input_str);
InsertSpacesBeforBigLetters(input_str);
Console::WriteLine(input_str);
Console::ReadKey();
return 0;
}
Программа, которая вставляем пробелы перед каждым большим символом строки, начиная
с 1 (используется .NET класс String). В этом примере при передаче аргумента по дескриптору,
его значение после выполнения функции остаётся таким же, как и при вхождении в функцию
- то есть при вызове функции и передаче ей строки по дескриптору в качестве аргумента
она не меняется.
2)
#include "stdafx.h"
#include
using namespace std;
using namespace System;
ref class SomeObj
{
public:
int num;
SomeObj()
{
num = 0;
}
SomeObj(int Num)
{
num = Num;
}
void Meth()
{
cout << "I'm an object with number " << num;
}
};
void Upgrade(SomeObj ^smo)
{
smo->num = smo->num + 1;
}
int main()
{
SomeObj ^so = gcnew SomeObj(1);
so->Meth();
Upgrade(so);
cout << "\n";
so->Meth();
Console::ReadKey();
return 0;
}
Здесь же имеется написанный мною, в качестве примера, ссылочный класс SomeObj, который
находится в аналогичной ситуации, как и строка в прошлом примере, но при его передаче
по дескриптору в метод Upgrade его значение меняется.
Вопрос: почему так происходит? По идеи, в обоих случаях состояние объекта должно
меняться, ведь в официальной документации сказанно, что дескриптор ведёт себя как указатель
на объект. Или я что-то не так понял?
Ответы
Ответ 1
Вообщем я, походу, понял в чём проблема. При вызове функции создаётся новый указатель, которому присваивается значение, находящееся в указателе, который мы передаём этой функции. Тамким образом во 2 примере мы изменяем значение num объекта, на который указывает so. В первом же примере значение не меняется по той причине, что мы меняем знаение не объекта, по адресу который мы передали в качестве аргумента в функцию, а мы меняем значение указателя, который располагается в функции. Решение этой проблемы - передача объекта в функцию по ссылке, например: String ^%str.
Комментариев нет:
Отправить комментарий