Кс + + варијабле

Белешка

Интересне групе заједнице сада су прешле са Иаммер-а на < ДИЦТ__Мицрософт ⚐ Вива ⚐ Енгаге > Мицрософт Вива Енгаге . Да бисте се придружили < ДИЦТ__Вива ⚐ Енгаге > Вива Енгаге заједници и учествовали у најновијим дискусијама, попуните образац &лт;c0&гт;Захтев за приступ финансијама и операцијама < ДИЦТ__Вива ⚐ Енгаге > Вива Енгаге заједници&лт;/c0&гт; и изаберите заједницу којој желите да се придружите.

Овај чланак описује променљиве у X + +.

  • Променљива је идентификатор који указује на меморијску локацију на којој се чувају информације одређеног типа података. Величина , прецизност, подразумевана вредност, имплицитне и експлицитне функције конверзије и опсег зависе од типа података променљиве.
  • Обим променљиве дефинише област у коду где се може приступити ставци.
  • Инстанце променљиве су декларисане у декларацијама класе, и можете им приступити из било које методе у класи или из метода које проширују класу.
  • Локалним променљивим се може приступити само у блоку где сте их дефинисали.
  • Када декларишете променљиву, додељујете меморију и иницијализујете променљиву на подразумевану вредност.
  • Можете доделити вредности и статичким пољима и пољима инстанци као део декларације изјаве.
  • Можете декларисати променљиве било где у блоку кода у методу. Не морате их декларисати на почетку методе.
  • Константе су променљиве где се вредност не може променити када декларишете променљиву. Они користе кључну реч цонст или реадонлy .
  • Константе се разликују од поља само за читање на само један начин. Можете доделити вредност пољима само за читање само једном, и та вредност се никада не мења. Можете доделити пољу његову вредност било у линији, на месту где је поље декларисано, или у конструктору.

Када декларишете променљиве управљаних типова који нису аутори у X + +, имате две опције. Можете у потпуности квалификовати имена типа у декларацији укључивањем пуног именског простора, или можете додати изјаву усинг у вашу датотеку и затим изоставити именски простор из имена типа.

Варијабилни примери

// An example of two valid variable names.
str variableName;
CustInfo custNumber;

// An example of simultaneously declaring and initializing a variable.
real pi = 3.14159265359; // Assigns value of pi to 12 significant digits.

// An example of initializing an object by using the new method on the class.
Access accessObject = new Access(); // Simple call to the new method in the Access class.

// An example of multiple declarations using integers.
int i,j; // Declares 2 integers, i and j.

// An example of multiple declarations using an array.
int a[100,5], b=1; // Declares array with 100 integers with 5 in memory and b as an integer with value 1.

// An example of how variable scopes work.
class ScopeExample
{
    // The variable a is declared within the class.
    int a;

    // Because the method below is declared within the class,
    // it can access all the variables defined within the class.
    void aNewMethod()
    {
        // The variable b is declared within the method.
        // It can only be accessed by this method.
        int b;
    }
}

// An example of an assignment of field members inline.
public class FieldAssignmentExample
{
    int field1 = 1;
    str field2 = "Banana";
    void new()
    {
        // ...
    }
}

class ConstantExample
{
    // An example of a constant being declared at the class level.
    public const str MyContent = 'SomeValue';
    public int ResultSoFar()
    {
        return 1;
    }
}

// The constants can then be referenced by using the double-colon syntax.
str value = ConstantExample::MyContent;
// If you're in the scope of the class where the const is defined,
// you can omit the type name prefix (ConstantExample in this example).

// An example of the using clause where the alias can denote
// namespaces and classes.
using System;
using IONS=System.IO; // Namespace alias.
using Alist=System.Collections.ArrayList; // Class alias.
public class NamespaceExample
{
    public static void Main(Args a)
    {
        Int32 I; // Alternative to System.Int32.
        Alist al; // Using a class alias.
        al = new Alist();
        str s;
        al.Add(1);
        IONS.Path::ChangeExtension(@"c:\tmp\test.xml", ".txt");
    }
}

Вар

Можете декларисати променљиву без експлицитног давања типа променљиве ако компајлер може да одреди тип из израза иницијализације. Променљива је и даље снажно откуцана у један недвосмислен тип.

Можете користити вар само на декларацијама где дајете иницијализацијске изразе. Компајлер закључује тип из израза иницијализације. У неким случајевима, овај приступ може олакшати читање кода.

Користите вар да декларишете локалне променљиве у следећим ситуацијама:

  • Када је тип променљиве очигледан са десне стране задатка
  • Када тачан тип није важан
  • За декларације бројача за петље
  • За предмете за једнократну употребу унутра користећи изјаве

Не користите вар када тип није јасан из израза иницијализације.

вар примери

// When the type of a variable is clear from
// the context, use var in the declaration.
var var1 = "This is clearly a string.";
var var2 = 27; // This is an integer (not a real).
var i = System.Convert::ToInt32(3.4);

// Don't use var when the type of the variable is not clear
// from the context. Use an explicit type instead.
int var4 = myObject.ResultSoFar();

Декларишите било где

Сада можете да пружите декларације где год можете да дате изјаве. Декларација је синтактички изјава, тако да је изјава декларације .

Можете да обезбедите декларације непосредно пре него што користите променљиву, и не морате да декларишете све променљиве на једном месту. Дакле , имате прецизну контролу над обимом ваших варијабли.

Можете дати варијаблама мање опсеге, изван којих не можете да се реферишете на варијабле. Животни век променљиве је обим у којем је декларисана. Можете покренути опсеге на нивоу блока (унутар сложених изјава ), у фор изјавама, и у коришћењу изјава.

Постоји неколико предности прављења опсега малим:

  • Читљивост је побољшана.
  • Смањујете ризик да се променљива поново користи на неприкладан начин током дугорочног одржавања кода.
  • Лакше је рефакторирати код. Можете копирати у коду без бриге да ће променљиве бити поново употребљене у контекстима где не би требало да буду поново употребљене.

У следећем примеру, декларишете бројач петље унутар фор израза у којем га користите.

void MyMethod()
{
    for (int i = 0; i < 10; i++)
    {
        info(strfmt("i is %1", i));
    }
}

Обим променљиве је сама фор изјава, и укључује израз услова и делове за ажурирање петље. Не можете користити вредност изван овог опсега.

У следећем примеру, када компајлер достигне инфо изјаву, он враћа следећу поруку о грешци: "'и' није декларисано."

void MyMethod()
{
    for (int i = 0; i < 10; i++)
    {
        if (i == 7)
        {
            break;
        }
    }
    // The next statement causes a compiler error.
    info(strfmt("Found: %1", i));
}

Такође можете да обухватите променљиве на користећи изјаву, као што је приказано у следећем примеру.

static void AnotherMethod()
{
    str textFromFile;
    using (System.IO.StreamReader sr = new System.IO.StreamReader("c:\\test.txt"))
    {
        textFromFile = sr.ReadToEnd();
    }
}

Када користите објекат који имплементира ИДиспосабле , декларишите и инстанцирајте тај објекат у наредби употребе . Наредба усинг позива метод Диспосе на објект исправно, чак и ако се изузетак јавља док позивате методе на објекту. Можете постићи исти резултат стављањем објекта унутар блока покушаја , а затим експлицитно позивањем Располажи у блоку коначно . У ствари, компајлер преводи изјаву о коришћењу управо на овај начин.

Следећи пример приказује неке од карактеристика које овај одељак описује.

// loop variable declared within the loop: It will
// not be misused outside the loop
for(int i = 1; i < 10; i++)
{
    // Because this value is not used from outside the loop,
    // its declaration belongs in this smaller scope.
    str s = int2str(i);
    info(s);
}

Да би се спречила конфузија, компајлер враћа поруку о грешци ако покушате да унесете променљиву која скрива другу променљиву у обиму који затвара, или чак у истом обиму. На пример, следећи код изазива компајлер да врати следећу дијагностичку поруку: "Локална променљива под називом 'и' не може бити декларисана у овом обиму јер би дала другачије значење 'и', који се већ користи у родитељском или тренутном опсегу да означи нешто друго."

{
    int i;
    {
        int i;
    }
}

Константе , варијабле само за читање и макрои

Језик у потпуности подржава концепт макроа. Константе нуде следеће предности у односу на макрое:

  • Можете додати коментар документације константи, али не и вредности макроа. На крају, језичка служба преузима овај коментар и пружа корисне информације кориснику.
  • ИнтеллиСенсе препознаје константу.
  • Константа је унакрсно референцирана. Стога , можете пронаћи све референце за одређену константу, али не и за макро.
  • Константа је подложна модификаторима приступа. Можете користити приватне , заштићене и јавне модификаторе. Доступност макроа није ригорозно дефинисана.
  • Константне варијабле имају опсег, док макрои немају опсег.
  • Можете видети вредност константе или променљиве само за читање у програму за отклањање грешака.

Макрои које дефинишете у обимима класа (то јест, у декларацијама класа) су ефективно доступни у свим методама свих изведених класа. Ова особина је првобитно била грешка у имплементацији наслеђеног макроа компајлера. Међутим , многи програмери апликација сада то користе. X + + компајлер и даље поштује ову особину, али немојте писати нови код који га користи. Ова особина такође има значајан утицај на перформансе компајлера.

Као опцију, можете користити макро на нивоу декларација класе, али са специфичним позивањем на вредност у том макроу. Овај приступ нема утицаја на перформансе компајлера. Можете омогућити постојећим стандардним макроима да имају унакрсне референце (као и све могућности константне варијабле) у вашем развоју.

private const int RetryNum = #OCCRetryCount#RetryNum;

Можете декларисати константе на нивоу класе, као што је приказано у следећем примеру.

private const str MyConstant = 'SomeValue';

Можете се позвати на константе користећи двоструку двотачку (::) синтаксу.

str value = MyClass::MyConstant;

Ако сте у оквиру класе где дефинишете константу ( цонст ), можете изоставити префикс имена типа ( МyЦласс у претходном примеру). Због тога можете лако имплементирати концепт макро библиотеке. Листа макро симбола постаје класа која има јавне дефиниције цонст .

Такође можете дефинисати константе само као променљиве. Компајлер одржава инваријанту тако да вредност не може бити модификована.

{
    const int Blue = 0x0000FF;
    const int Green = 0x00FF00;
    const int Red = 0xFF0000;
}

Можете доделити вредност пољима само за читање само једном, и та вредност се никада не мења. Можете доделити пољу његову вредност било у линији, на месту где је поље декларисано, или у конструктору.

Нулте вредности за типове података

Многи други системи за управљање базама података (ДБМС) подржавају концепт нултих вредности, али Кс + + не подржава овај концепт. Променљива у Кс + + увек има тип и вредност. Међутим , за сваки тип података, једна вредност се сматра нултом (на пример, када се покрене метод валидатеФиелд табеле).

Тип Вредност која се третира као нула
Датум 1900-01-01
Енумерација Елемент који има своју вредност подешену на 0
Integer 0
Стварно 0.0
String Празан низ
Време 00:00:00
Утцдатетиме Свака вредност која има свој део датума подешен на 1900-01-01, без обзира на вредност временског дела. На пример, вредност 1900-01-01T22:33:44 се третира као нула . Имајте на уму да X + + принт изјава приказује било коју утцДатеТиме вредност која има свој део датума подешен на 1900-01-01 као празан. Само метод Глобал::инфо показује вредност 1900-01-01T00:00:00 као празно. Та вредност је вредност из методе ДатеТимеУтил::МинВалуе .

Када валидатеФиелд метод проверава да ли корисник уноси вредност у обавезно поље, 0 није прихваћен у пољу целог типа , први унос није прихваћен у пољу типа енум , и тако даље. Поред тога, у СКЛ Кс + + изјавама, вредности које су наведене у претходној табели дају лаж у Боолеовом поређењу. Међутим , у не-СКЛ X + + изјавама, једнаки и релацијски оператори раде са овим вредностима, баш као што раде са другим вредностима. Варијабле типа контејнера , и класе и варијабле типа табеле могу бити нула у традиционалном ДБМС смислу. Тип табеле је нулл ако сва његова поља имају своју нулт вредност.

Ливење

Цастинг се односи на задатке између варијабли чији декларисани типови су оба у истом ланцу наслеђивања. Цаст је или доле или горе. Размотрите следећу хијерархију класе.

Снимак екрана хијерархије класе за животиње и моторна возила.

Класа МоторВехицле није повезана са класом Анимал, иако обе потичу од Објецт. Уп -цаст се дешава када доделите израз изведеног типа основном типу:

Animal a = new Horse();

Довн -цаст се дешава када доделите израз основног типа изведеној променљивој.

Horse h = new Animal();

Кс + + подржава и горе-цастс и довн-цастс. Међутим , довн-цастс су опасни и треба их избегавати кад год је то могуће. Довн -цаст пример у претходном коду не успева са InvalidCastException у рунтиме, јер задатак нема смисла. X + + подржава касно везивање на неколико типова, као object што су и formrun. Ова подршка значи да компајлер не дијагностикује никакве грешке у време компајлирања када види метод који се позива на те типове, ако тај метод није експлицитно декларисан на типу. Претпоставља се да програмер зна шта ради. На пример, следећи код се може наћи у форми.

Object o = element.args().caller();
    o.MyMethod(3.14, “Banana”);

Компајлер не може да провери параметре или повратне вредности за метод, MyMethod јер овај метод није декларисан на класи објекта. У време извођења, позив се врши помоћу рефлексије, што је много спорије од позива који не захтевају рефлексију. Проверавају се позиви на методе које су дефинисане на типовима касног везивања. На пример, позив у ToString следећем примеру:

o.ToString(45);

Изазива грешку компилације:

'Object.toString' expects 0 argument(s), but 1 specified.

јер ToString је метод дефинисан на класи object . Постоји једна разлика у односу на имплементацију у претходним верзијама X + + (AKS2012 и раније) која се односи на чињеницу да се методе могу позвати на неповезане објекте, све док је име методе било тачно, чак и ако профили параметара нису били потпуно тачни. Ова подршка више није доступна.

Пример - ливење

public class MyClass2
{
    public static void Main(Args a)
    {
        Object obj = new Car();
        Horse horse = obj; // exception now thrown
        horse.run();    // Used to call car.run()!
    }
}

Користите is и as операторе слободно у вашем коду. Користите is оператор да проверите да ли је дати израз одређеног типа (укључујући и изведене типове). Оператор as врши ливење у датом типу и враћа нулл ако цаст није могуће.