C ++ Объединенные поля не установлены правильно

У меня есть шаблонный тип объединения NodeType.
Проблема заключается в том, что при присвоении его переменной поля не устанавливаются должным образом, а при последующем доступе содержат значения мусора. В частности, проблема возникает с _field1 и _field2 — см. Основные.

#include <cstdlib>
#include <iostream>

using namespace std;template <class T>
struct structExampleType
{
T _structField;
typedef structExampleType<T>* pointerStructExample;
};enum TYPE_tag
{FIELD1_tag, FIELD2_tag} TYPE_tag;

template <class T>//, class P>
union NodeType
{
enum TYPE_tag _nodeType_tag;
char _field1;
typename structExampleType<T>::pointerStructExample _field2;

NodeType(){_field2=0;}

NodeType(enum TYPE_tag nodeType_tag, char _charField)
{
_nodeType_tag=nodeType_tag;
_field1=_charField;
//_field2=0;
}

NodeType(enum TYPE_tag nodeType_tag, typename structExampleType<T>::pointerStructExample pointer)
{
_nodeType_tag=nodeType_tag;
_field2=pointer;
//_field1='-';
}

};int main(int argc, char *argv[])
{
NodeType<int> node1, node2;
structExampleType<int>* structExamplePointer;

structExamplePointer=new structExampleType<int>();

structExamplePointer->_structField=100;
//    structExamplePointer->_field2=structExamplePointer;

node1=NodeType<int>(FIELD1_tag,'-');
node2=NodeType<int>(FIELD2_tag,structExamplePointer);cout<<endl<<"node1: ";
if (node1._nodeType_tag==FIELD1_tag)
{cout<<node1._field1<<endl;}
else
{cout<<node1._field2<<endl;}cout<<endl<<"node2: ";
if (node2._nodeType_tag==FIELD2_tag)
{cout<<node2._field1<<endl;}
else
{
cout<<node2._field2<<endl;
cout<<(node2._field2)->_structField<<endl;
}system("PAUSE");
return EXIT_SUCCESS;
}

В чем может быть проблема? Спасибо заранее за ваше время.

0

Решение

В main у вас есть эти две строки:

structExampleType<int>* structExamplePointer;

structExamplePointer->_structField=100;

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

Вы также, кажется, неправильно понимаете цель union, так как вы пытаетесь установить несколько полей. В union все поля доля то же пространство, поэтому при записи одному члену все члены меняются. Действителен только последний написанный члену. Попытка использовать другие поля может снова привести к неопределенному поведению.


Если вам нужно иметь поле «тег» а также другие данные, структура, содержащая тег и данные объединения, должны быть на ваш выбор:

struct NodeType
{
enum TAG_Type
{
FIELD1,
FIELD2
} type;

union
{
char field1;
struct some_struct* field2;
}
};
3

Другие решения

С union члены пытаются занять одно и то же место в памяти, поэтому ваш конструктор вызывает проблему, назначая каждому члену и перезаписывая друг друга.

Объединение настолько велико, насколько необходимо, чтобы вместить самого большого члена данных. Другие элементы данных размещаются в тех же байтах, что и часть этого самого большого элемента.

2

То, что вы на самом деле имеете здесь, это не объединение field1 и field2, а объединение {tag, field1, field2}. Вот почему вы видите мусор. Union по-прежнему остается одной областью памяти, но вы устанавливаете ее три раза в логике построения.

Вы можете начать с более простых случаев и прочитать некоторую документацию, например, http://msdn.microsoft.com/en-us/library/5dxy4b7b.aspx

Чтобы достичь своих целей, вы можете сделать что-то подобное (вам нужно, чтобы ваш тег был внешним по отношению к объединению):

союз MyUnionType
{
int data_int;
double data_double;
}

typedef enum {IntTag, DoubleTag} UnionTypeTag;

класс MyVariableClass
{
частный:
MyUnionType m_variableField;
UnionTypeTag m_variableFieldType;
}

Другой подход состоит в том, чтобы спроектировать ваш код так, чтобы в любой точке пути кода вы знали, какой «тип» типа объединения вы обрабатываете.

Мое личное мнение таково, что последний (всегда зная, какой твой союз «флейвор») имел в виду К&R, когда они думали о концепции союза.

2

Можете ли вы инициализировать указатель structExampleType<int>* structExamplePointer перед его использованием.

Поскольку разыменование неинициализированного указателя является причиной проблемы

0
По вопросам рекламы [email protected]