1

Create an “UnusualClass” class in which direct and copy initialization produce different effects throughout. In particular, the attempt of direct or copy initialization should produce on the screen the print "Direct initialization" or "Copy initialization"

#include <iostream>
class UnusualClass{
   public:
   UnusualClass(const int &n){
       std::cout<<"Copy initialization";
   }
   UnusualClass &operator=(const int &n){
       std::cout<<"Direct initialization";
   }
};
int main ()
{
    UnusualClass k1(5); // Should print "Direct initialization"
    UnusualClass k2 = 5; // Should print "Copy initialization"
    return 0;
}

Why do I get copy initialization for both cases?

How to make UnusualClass k1(5); prints "Direct initialization" and UnusualClass k2 = 5; prints "Copy Initialization"?

Rocket Procd
  • 103
  • 10
  • There is no **assignment** in your given example and hence the assignment `operator=` will not be used for your given example. – Jason May 28 '22 at 14:14
  • how to make this work as expected? I'm new to object oriented programming, could you help me? – Rocket Procd May 28 '22 at 14:14
  • The `operator=` that you've provided is an assignment operator and inside it the `cout` statement should instead be `std::cout<<"Assignment operator";`. Ofcourse that won't change the output of the program though. – Jason May 28 '22 at 14:16
  • Replace `UnusualClass k2 = 5;` with `k1 = 5;` and you will get your expected output. – Jason May 28 '22 at 14:17
  • how to make `UnusualClass k1(5);` prints "Direct initialization" and `UnusualClass k2 = 5;` printes "Copy Initialization"? – Rocket Procd May 28 '22 at 14:18
  • Where did you find this exercise? If you're new, this is way above your "paygrade". – HolyBlackCat May 28 '22 at 14:18
  • @RocketProcd You can't . `UnusualClass k2 = 5;` is initialization and not an assignment. Though you can get the expected output by changing `UnusualClass k2 = 5;` with `k1 = 5;` – Jason May 28 '22 at 14:19
  • @HolyBlackCat it's just one from our laboratory exercise on which we do programming tasks on course Techniques of Programming – Rocket Procd May 28 '22 at 14:20
  • @AnoopRana I cannot change anything, it should work as in given example – Rocket Procd May 28 '22 at 14:21
  • @RocketProcd The symbol `=` doesn't necessarily mean assignment in C++. It is also used in copy initialization in addition to copy assignment. – Jason May 28 '22 at 14:21
  • thank you very much, so I shouldn't use operator =, but what to use to make this work as expected? – Rocket Procd May 28 '22 at 14:23
  • @RocketProcd You said *"I cannot change anything, it should work as in given example"*. Then how can we do anything about the given program? Are we allowed to change the program a little bit? For example, you will get your expected output if you use `k1 = 5;`. See [demo](https://onlinegdb.com/s2ixol4FO). But again it is not direct initialization it is assignment. – Jason May 28 '22 at 14:24
  • this `UnusualClass k1(5); UnusualClass k2 = 5;` cannot be changed. Anything else can. I need to fix my class to give correct output. This `UnusualClass k1(5); UnusualClass k2 = 5;` will be tested with autotester so it mustn't be changed – Rocket Procd May 28 '22 at 14:26
  • [Direct initialization](https://en.cppreference.com/w/cpp/language/direct_initialization) and [Copy initialization](https://en.cppreference.com/w/cpp/language/copy_initialization). What the code calls "copy initialization" is *direct initialization*. What the code calls "direct initialization" is *assignment* (and not even *copy assignment*, it's an assignment overload). – Eljay May 28 '22 at 14:31
  • [This](https://godbolt.org/z/Mz81z88h6) very nearly works and is in keeping with the spirit of the output: The copy constructor prints "copy initialization" and the converting constructor prints "direct initialization". However, you do get two prints of "direct initialization" because the prvalue that gets copied must, itself, be initialized. – Nathan Pierson May 28 '22 at 14:33
  • @RocketProcd Please use a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to learn C++. Doing exercises without having the basics clear will only result in [Cargo cult programming](https://en.wikipedia.org/wiki/Cargo_cult_programming) – Jason May 28 '22 at 14:36
  • @AnoopRana I posted my answer, it was just simple fix I needed... thank you very much – Rocket Procd May 28 '22 at 14:37

2 Answers2

1

I believe it's impossible in general, but if you only want to support the two ways of initialization you listed, there are hacky solutions.


You need two constructors, one explicit and the other non-explicit. As you were already told in comments, operator= won't help you, since both lines perform initialization and not assignment.

However, if the there are no other differences between the two constructors, the code won't compile.

You need to make the explicit constructor "better" than its non-explicit counterpart, so that it will be preferred if possible (i.e. for direct-initialization), so the other is used as a fallback.

Figuring out how exactly to make one constructor "better" than the other is left as an exercise to the reader. There are at least three approaches:

  • Using lvalue references vs rvalue references.
  • Using ....
  • Using a helper class with a constructor with an int parameter.
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
0

As suggested by @HolyBlackCat

This will work as expected.

#include <iostream>
class UnusualClass{
   public:
   UnusualClass(const int &n){
       std::cout<<"Copy initialization";
   }
   explicit UnusualClass(const int &&n){
       std::cout<<"Direct initialization";
   }
};
int main ()
{
    UnusualClass k1(5); 
    UnusualClass k2 = 5; 
    return 0;
}
Rocket Procd
  • 103
  • 10