C ++ that accepts any type of data without using patterns?

I have an assignment that asks to write a function for any data type. The function is supposed to print structure bytes and identify the total number of bytes that the data structure uses, and differentiate the bytes used for members and bytes used for padding.

My immediate reaction, along with most class reactions, was to use templates. This allows you to write a function once and collect the runtime type of the objects passed to the function. Using memset and typeid, you can easily accomplish what was set. However, our prof. just saw our discussion of patterns and damned patterns in hell.

Seeing this, I was thrown for a cycle, and I'm looking for a little guidance as the best way to get around this. Some things that I looked at:

  • explicit cast void pointers (it looks like it will be randomly)
  • a base class with virtual functions, from which all data structures are inherited, seems a little strange.
  • a base class with "friendship" for each of our data structures.
  • rewriting a function for each data structure in our set of problems (I think this is the worst possible solution).

I was hoping I missed the general C ++ tool, does anyone have any ideas?

+4
source share
3 answers

, , , , .

:

  • , uint8_t *. ( )
  • . ( )
  • : , .

, , , . .

:

  void Analyze_Structure(uint8_t const *  p_structure,
                         size_t           size_of_structure,
                         size_t           size_occupied_by_members);

, , .

, .

1:

struct Apple
{
  char    a;
  int     weight;
  double  protein_per_gram;
};

int main(void)
{
  Apple granny_smith;
  Analyze_Structure((uint8_t *) &granny_smith,
                    sizeof(Apple),
                    sizeof(granny_smith.a)
                    + sizeof(granny_smith.weight)
                    + sizeof(granny_smith.protein_per_gram);
  return 0;
}
+1

, .

( ), void *, ( printf).

,

void your_function(void* data, std::size_t size)
{
    std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(data);

    for(auto x = bytes; x != bytes + size; ++x)
        std::clog << "0x" << std::hex << static_cast<std::uint32_t>(*x) << " ";
}

[...] , , , , , .

: , , ( ) . :

struct x { char c; char d; char e; }; // sizeof(x) == 3;

x instance{ 0, 0, 0 };
your_function(&instance, sizeof(x)); // passes 3, not 4 (4 for 32bits architecture)

alignof(instance) , ( , , ).

:

  • . "" ++, 10 20 ( C-, , " " ).

  • , , , ( " " ) : , , , - , " ?" " " ).

    , - - - , , , , , .

  • , - (, struct x ) API ().

+1

, : , , .

, , , "".

void * size_t sizeof .

0) .

1) , 0.

2) .

3) , , 0.

4) , 1.

5), . ( , !)

6) , 1 . .

0, 1 , , , 0; 0 1 , .

struct _S { int I; char C } S;

Fill0(S, sizeof(S));

// User cooperation
S.I= 0;
S.C= '\0';

Mark0(S, sizeof(S)); // Has some form of static storage

Fill1(S, sizeof(S));

// User cooperation
S.I= 0;
S.C= '\0';

DetectPadding(S, sizeof(S));

, , .

void Assign(void* pS) // User-written callback
{
  struct _S& S= *(struct _S)pS;

  S.I= 0;
  S.C= '\0';
}
0

All Articles