1

Code-1

#include <iostream>
#include <cstring>
class A
{
private:
    int p[5];
    char str[20];
public:
    A(int *q, char *s)
    {
        for(int i=0; i<=4; i++)
        {
            p[i]=*q;
            q++;
        }
        strcpy(str,s);
    }

};

int main()
{
    int r[5]={2, 3, 5, 7, 11};
    char ch[]="bonaparte";
    A a1(r, ch);
    
    return 0;
}

Output ( Runs smoothly but just gives warning )

Clang-Tidy: Constructor does not initialize 
these fields: p, str

Why this warning is coming. I know that I am assigning in constructor not initializing but When I create simple class which just have int type variable and If I assign that in this same way it didn't give such warning ?

Code-2

#include <iostream>
#include <cstring>
class A
{
private:
    int p[5];
    char str[20];
public:
    A(int *q, char *s):  // just not getting how we can do this initialization
    {

    }
};

int main()
{
    int r[5]={2, 3, 5, 7, 11};
    char ch[]="bonaparte";
    A a1(r, ch);
   
    return 0;
}

Is there any way to initialize int type or C-style char array via member initialization list through constructor.

I know that I can replace char array with string but I want to know a way for C-style char array.

2
  • 1
    You assign values to p & str in in the body of the constructor that's not initialization. Type A(const int* q, const char* s) : p{}, str{} { body... }. that will initialize p and str to all zeros (aggregate initialization). But I wouldn't advice you to use code like this, no size checks on the conten of q and s are possible. Either use const int (&q)[5], const std::array<int,5>& or consider const std::vector<int>& as parameters to your function so you can keep track of the actual sizes of your arrays Commented Oct 14, 2021 at 6:54
  • A(const int* q, const char* s) : p{}, str{} { body... } That worked. But how can we initialize with this const int (&q)[5] I think we can just assign only. Commented Oct 15, 2021 at 3:57

1 Answer 1

1

Arrays in C++ are not the friendliest bit of the language. Specialy not when you let them decay to pointers (size information is lost). So I prefer to use std::array, std::vector and std::string since these standard library classes help you prevent all sort of memory bugs.

About your initialization question, yes you can only assign in the body of the constructor. This is another reason I like std::array/std::vector better you can use them in the initializer. I also consider ::strcpy to be a left over from 'C' not to be used anymore in current C++. Have fun learning more C++ :)

#include <iostream>
//#include <cstring> // <== don't use this. (If you want to use strings in C++ use <string>

#include <vector>
#include <string>

// try to learn not to use what is called
// "magic numbers" in your source code!
// define numbers you are going to use
// 
const std::size_t int_array_size = 5;
const std::size_t string_array_size = 20;

// we don't know the length of the string yet, but we can let
// the compiler figure it out and we make a templated constructor
class A
{
public:
    // pass arrays in by const, you're not supposed to 
    // change their content.
    A(const int (&p)[int_array_size], const char (&str)[string_array_size])
    {
        // I always use std::size_t for indices in arrays (not supposed to be <0)
        for (/*int*/ std::size_t i = 0; i < int_array_size; i++) m_p[i] = p[i];

        // don't use ::strcpy it's not "safe". It depends on correct input
        // like the string having a trailing 0
        for (std::size_t i = 0; i < string_array_size; i++) m_str[i] = str[i];
    }

private:
    int m_p[int_array_size];
    char m_str[string_array_size];
};

// this is one way I would code it.
// using C++ with variable length array (so I use std::vector, for fixed length use std::array)
class B
{
public:
    B(const std::vector<int>& p, const std::string& str) :
        m_p{ p },
        m_str{ str }
    {
    }

private:
    std::vector<int> m_p; // or std::array<int,int_array_size>
    std::string m_str;
};

int main()
{
    // I prefer to use aggregate initialization (https://en.cppreference.com/w/cpp/language/aggregate_initialization)
    int r[int_array_size]{ 2, 3, 5, 7, 11 };
    
    // The next line is defined behavior. C++ standard says all remaining 
    // values of ch after bonaparte will be 0
    char ch[string_array_size]{ "bonaparte" };

    A a1(r, ch);

    B b1{ {1,2,3}, "hello world!" };

    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

first of all thanks for answer. In context of class B the first argument of constructor is const std::vector<int>& p taking reference and you are passing {1,2,3} but it's temporary so how can we store it's reference and my clion-ide is also giving Error :No matching constructor for initialization of 'A'
In my code-1 why it is giving warning ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.